How to use IO with Scalaz7 Iteratees without overflowing the stack?

前端 未结 1 2000
滥情空心
滥情空心 2020-12-31 12:11

Consider this code (taken from here and modified to use bytes rather than lines of characters).

import java.io.{ File, InputStream, BufferedInputStream, File         


        
相关标签:
1条回答
  • 2020-12-31 12:55

    After creating exceptions and printing their stack length in various place of your code, I felt that your code is not overflowing. All seems to run in constant stack size. So I looked for other places. Eventually I copied the implementation of consume and added some stack depth printing and confirmed it overflowed there.

    So this overflows:

    (I.consume[Int, Id, List] &= EnumeratorT.enumStream(Stream.fill(10000)(1))).run
    

    But, I then found out that this doesn't:

    (I.putStrTo[Int](System.out) &= EnumeratorT.enumStream(Stream.fill(10000)(1)))
      .run.unsafePerformIO()
    

    putStrTo uses foldM and somehow is not causing an overflow. So I am wondering whether consume can be implemented in terms of foldM. I just copied a few things over from consume and tweaked until it compiled:

    def consume1[E, F[_]:Monad, A[_]:PlusEmpty:Applicative]: IterateeT[E, F, A[E]] = {
      I.foldM[E, F, A[E]](PlusEmpty[A].empty){ (acc: A[E], e: E) =>
        (Applicative[A].point(e) <+> acc).point[F]
      }
    }
    

    And it worked! Printing a long list of ints.

    0 讨论(0)
提交回复
热议问题