使用 State monad 从流中进行可选解析
Optional parse from stream with State monad
我是猫的新手。我正在创建 State
个实例来处理字节流中类型的反序列化。例如
val int: State[Seq[Byte], Int] = State[Seq[Byte], Int] {
case bs if bs.length >= 4 =>
bs.drop(4) -> ByteBuffer.wrap(bs.take(4).toArray).getInt
case _ => throw new EOFException()
}
我已经根据上述实现了 Option[Int]
的解析器,如下所示:
val unit: State[Seq[Byte], Unit] = State[Seq[Byte], Unit](_ -> Unit)
val optInt: State[Seq[Byte], Option[Int]] = int.flatMap(i =>
if (i == 1) int.map(Some(_)) else unit.map(_ => None)
)
我觉得我在这里错过了一个技巧,因为实现似乎太冗长了。我可以更简洁地写这个吗?我可以不需要定义 unit
吗?
我不会说这太冗长,但我会用两个技巧来解决这个问题:
- 用模式匹配函数替换条件
- 使用
State.pure
而不是手动 creating/transforming State
值,例如您的 unit
.
val optInt: State[Seq[Byte], Option[Int]] = int.flatMap {
case 1 => int.map(Some(_))
case _ => State.pure(None)
}
我是猫的新手。我正在创建 State
个实例来处理字节流中类型的反序列化。例如
val int: State[Seq[Byte], Int] = State[Seq[Byte], Int] {
case bs if bs.length >= 4 =>
bs.drop(4) -> ByteBuffer.wrap(bs.take(4).toArray).getInt
case _ => throw new EOFException()
}
我已经根据上述实现了 Option[Int]
的解析器,如下所示:
val unit: State[Seq[Byte], Unit] = State[Seq[Byte], Unit](_ -> Unit)
val optInt: State[Seq[Byte], Option[Int]] = int.flatMap(i =>
if (i == 1) int.map(Some(_)) else unit.map(_ => None)
)
我觉得我在这里错过了一个技巧,因为实现似乎太冗长了。我可以更简洁地写这个吗?我可以不需要定义 unit
吗?
我不会说这太冗长,但我会用两个技巧来解决这个问题:
- 用模式匹配函数替换条件
- 使用
State.pure
而不是手动 creating/transformingState
值,例如您的unit
.
val optInt: State[Seq[Byte], Option[Int]] = int.flatMap {
case 1 => int.map(Some(_))
case _ => State.pure(None)
}