使用State monad从流中进行可选解析

时间:2018-12-21 11:37:06

标签: scala scala-cats

我是猫的新手。我正在创建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吗?

1 个答案:

答案 0 :(得分:2)

我不会说太冗长,但是我会用两个技巧:

  1. 使用模式匹配功能替换条件
  2. 使用State.pure代替手动创建/转换State之类的值,例如unit

val optInt: State[Seq[Byte], Option[Int]] = int.flatMap {
  case 1 => int.map(Some(_))
  case _ => State.pure(None)
}