我试图用
State
蒙纳德。我真的有一个
java.nio.ReadableByteChannel
我想用固定大小的块(比如4096字节)来读取它,然后把这些块中的一些记录组合起来(比如按行)。
为了保持纯fp风格,我定义了类型chunker:
type Chunker =
(List[Array[Byte]], Array[Byte]) => (List[Array[Byte]], Option[Array[Byte]])
现在使用提供的chunker递归地定义状态转换,如下所示:
def takeFirstElement(chunker: Chunker)(chunk: => Option[Array[Byte]]):
State[List[Array[Byte]], Option[Array[Byte]]] =
chunk match {
case None => State.pure(None)
case Some(ba) => scanNextChunk(chunker)(ba) flatMap {
case None => takeFirstElement(chunker)(chunk)
case v @ Some(a) => State.pure(v)
}
}
def scanNextChunk(chunker: Chunker)(chunk: Array[Byte]):
State[List[Array[Byte]], Option[Array[Byte]]] = State(chunker(_, chunk))
现在我为它写了一个简单的测试
def main(args: Array[String]): Unit = {
val chunker: Chunker = //some complicated chunker
val channel = //some channel
val buf = ByteBuffer.allocate(8)
val result = takeFirstElement(chunker) {
val bytesRead = channel.read(buf)
val data = if (bytesRead >= 0) {
val ba = new Array[Byte](bytesRead)
System.arraycopy(buf.array(), 0, ba, 0, bytesRead)
Some(ba)
} else
None
buf.clear()
data
}.run(List.empty)
println(new String(result.value._2.get))
}
它是有效的,但是在这个例子中有一些事情困扰着我。
-
我能利用一下吗
ReaderWriterStateT
并用定义的读取器替换名称参数。有可能吗?
-
是否可以添加
IO
在这里暂停副作用的语义
channel
提供?