代码之家  ›  专栏  ›  技术社区  ›  Some Name

状态转换为'state`

  •  3
  • Some Name  · 技术社区  · 7 年前

    我试图用 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))
    }
    

    它是有效的,但是在这个例子中有一些事情困扰着我。

    1. 我能利用一下吗 ReaderWriterStateT 并用定义的读取器替换名称参数。有可能吗?

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

    0 回复  |  直到 7 年前