scalaz-stream:如何串联连接?

时间:2015-03-03 12:54:02

标签: scala scalaz-stream

是否有一种惯用的块和连接方式?

我找到的方法(字节示例):

    1。
    import scodec.bits.ByteVector    
    
    def byteChunk(n: Int): Process1[ByteVector, ByteVector] =
        process1.chunk(n).map(_.reduce(_ ++ _))
    

    但在这种情况下,并不真正需要中间Vector(来自chunk)。

    1. 基于process1.chunk的复制/粘贴:
    2. def byteChunk(n: Int): Process1[ByteVector, ByteVector] = {
      
        def go(m: Int, acc: ByteVector): Process1[ByteVector, ByteVector] =
          if (m <= 0) {
            emit(acc) ++ go(n, ByteVector.empty)
          } else {
            def fallback = if (acc.nonEmpty) emit(acc) else halt
            receive1Or[ByteVector, ByteVector](fallback) { in =>
              go(m - 1, acc ++ in)
            }
          }
      
        go(n, ByteVector.empty)
      }
      

      是否有办法将现有的Process'es?

      组合起来

      一个附带问题:可以使用repeat代替++ go吗?这与前一个相同:

      def byteChunk(n: Int): Process1[ByteVector, ByteVector] = {
      
        def go(m: Int, acc: ByteVector): Process1[ByteVector, ByteVector] =
          if (m <= 0) emit(acc)
          else ...
      
        go(n, ByteVector.empty).repeat
      }
      

1 个答案:

答案 0 :(得分:0)

我认为你可以使用takelastscanMonoid

来简化这一点
def byteChunk(n: Int): Process1[ByteVector, ByteVector] = {
  process1.take[ByteVector](n).scanMonoid.last ++ Process.suspend(go(n))
}

(如果您不希望实施scanMonoid,请将.scan(ByteVector.empty)((acc, x: ByteVector) => acc ++ x)替换为Monoid[ByteVector]

Process.repeat似乎可以工作而不是++ Process.suspend(go(n)),并且Process.repeat的实施方式表明,只要byteChunk(n)是纯粹的,它就会成立。