国家过渡与“国家”

时间:2018-06-05 14:56:30

标签: scala functional-programming scalaz scala-cats

我尝试使用State monad设计状态转换。我实际上有一个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))
}

它有效,但在这个例子中有些东西困扰我。

  1. 我可以使用ReaderWriterStateT并使用已定义的阅读器替换名称参数。有可能吗?

  2. 是否可以在此处添加IO语义来暂停channel提供的副作用?

0 个答案:

没有答案