I'm new to cats. I'm creating State
instances to handle deserialisation of types from a byte stream. e.g.
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()
}
I have implemented a parser of Option[Int]
in terms of the above, like so:
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)
)
I feel that I've missed a trick here, as the implementation seems too verbose. Can I write this more succinctly? Can I do away with needing to define unit
?
I wouldn't say that's too verbose, but I'd do two tricks with this:
State.pure
instead of manually creating/transforming State
values such as your unit
.val optInt: State[Seq[Byte], Option[Int]] = int.flatMap {
case 1 => int.map(Some(_))
case _ => State.pure(None)
}