Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>EDIT here is the real solution. I left in the original post because I think its worthwhile seeing the pattern. What works for Klesli works for IterateeT</p> <pre><code>import java.io.{ BufferedReader, File, FileReader } import scalaz._, Scalaz._, effect._, iteratee.{ Iteratee =&gt; I, _ } object IterateeIOExample { type ErrorOr[+A] = EitherT[IO, Throwable, A] def openFile(f: File) = IO(new BufferedReader(new FileReader(f))) def readLine(r: BufferedReader) = IO(Option(r.readLine)) def closeReader(r: BufferedReader) = IO(r.close()) def tryIO[A, B](action: IO[B]) = I.iterateeT[A, ErrorOr, B] { EitherT.fromEither(action.catchLeft).map(r =&gt; I.sdone(r, I.emptyInput)) } def enumBuffered(r: =&gt; BufferedReader) = new EnumeratorT[String, ErrorOr] { lazy val reader = r def apply[A] = (s: StepT[String, ErrorOr, A]) =&gt; s.mapCont(k =&gt; tryIO(readLine(reader)) flatMap { case None =&gt; s.pointI case Some(line) =&gt; k(I.elInput(line)) &gt;&gt;== apply[A] }) } def enumFile(f: File) = new EnumeratorT[String, ErrorOr] { def apply[A] = (s: StepT[String, ErrorOr, A]) =&gt; tryIO(openFile(f)).flatMap(reader =&gt; I.iterateeT[String, ErrorOr, A]( EitherT( enumBuffered(reader).apply(s).value.run.ensuring(closeReader(reader))))) } def main(args: Array[String]) { val action = ( I.consume[String, ErrorOr, List] %= I.filter(a =&gt; a.count(_ == '0') &gt;= 25) &amp;= enumFile(new File(args(0)))).run.run println(action.unsafePerformIO().map(_.size)) } } </code></pre> <p>===== Original Post =====</p> <p>I feel like you need an EitherT in the mix. Without EitherT you are just ending up with a 3 Lefts or Rights. With EitherT it would propergate the left. </p> <p>I think what you really want is</p> <pre><code>type ErrorOr[+A] = EitherT[IO, Throwable, A] I.iterateeT[A, ErrorOr, B] </code></pre> <p>The following code mimics how you are currently composing things. Because IterateeT has no concept of left and right, when you compose it, you just end up with a bunch of IO/Id's.</p> <pre><code>scala&gt; Kleisli((a:Int) =&gt; 4.right[String].point[Id]) res11: scalaz.Kleisli[scalaz.Scalaz.Id,Int,scalaz.\/[String,Int]] = scalaz.KleisliFunctions$$anon$18@73e771ca scala&gt; Kleisli((a:Int) =&gt; "aa".left[Int].point[Id]) res12: scalaz.Kleisli[scalaz.Scalaz.Id,Int,scalaz.\/[String,Int]] = scalaz.KleisliFunctions$$anon$18@be41b41 scala&gt; for { a &lt;- res11; b &lt;- res12 } yield (a,b) res15: scalaz.Kleisli[scalaz.Scalaz.Id,Int,(scalaz.\/[String,Int], scalaz.\/[String,Int])] = scalaz.KleisliFunctions$$anon$18@42fd1445 scala&gt; res15.run(1) res16: (scalaz.\/[String,Int], scalaz.\/[String,Int]) = (\/-(4),-\/(aa)) </code></pre> <p>In the following code, instead of using Id, we use an EitherT. Since EitherT has the same bind behaviour as Either, we end up with what we want.</p> <pre><code>scala&gt; type ErrorOr[+A] = EitherT[Id, String, A] defined type alias ErrorOr scala&gt; Kleisli[ErrorOr, Int, Int]((a:Int) =&gt; EitherT(4.right[String].point[Id])) res22: scalaz.Kleisli[ErrorOr,Int,Int] = scalaz.KleisliFunctions$$anon$18@58b547a0 scala&gt; Kleisli[ErrorOr, Int, Int]((a:Int) =&gt; EitherT("aa".left[Int].point[Id])) res24: scalaz.Kleisli[ErrorOr,Int,Int] = scalaz.KleisliFunctions$$anon$18@342f2ceb scala&gt; for { a &lt;- res22; b &lt;- res24 } yield 2 res25: scalaz.Kleisli[ErrorOr,Int,Int] = scalaz.KleisliFunctions$$anon$18@204eab31 scala&gt; res25.run(2).run res26: scalaz.Scalaz.Id[scalaz.\/[String,Int]] = -\/(aa) </code></pre> <p>You can replace Keisli with IterateeT and Id with IO to get what you need.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload