[Haskell-cafe] [iteratee] how to do nothing .. properly

John Lato jwlato at gmail.com
Sun Jun 5 17:02:56 CEST 2011


Yes, this is expected.  'throwErr' is only meant to be used when the error
should be non-recoverable, and the stream would often be invalid then, so
throwErr doesn't take any steps to preserve it.  You could retain the rest
of the stream with getChunk and use throwRecoverableErr though.

Wrapping an iteratee with ErrorT is fine, and I use this approach often.  I
typically would use an explicit Either rather than ErrorT, but the two
approaches are exactly the same.

Note that wrapping the other way, Iteratee s (ErrorT e m), can sometimes
cause problems, and is best avoided unless you really know what you're
doing.  This may change in a future release.

John

On Thu, Jun 2, 2011 at 4:27 PM, Sergey Mironov <ierton at gmail.com> wrote:

> I am glad to help! Looks like upgrading to 0.8.5.0 also fixes initial
> problem that involved me into testing!
>
> I'll take the opportunity and ask another thing about iteratee: Is it
> expected behavior that throwErr consumes all data in current chunk? I
> wish it to stop in place and let after-checkErr code to continue the
> parsing. Well, I already found solution (or workaround?) - I wrap
> Iteratee with ErrorT monad and use ErrorT's raiseError instead of
> throwErr. Is it correct?
>
> Here is example code
>
> instance Exception Int
>
> iter4 = do
>    I.dropWhile (/= 3)
>    h<-I.head
>    throwErr $ toException $ (-4::Int)  -- doesn't meter what exactly to
> throw
>    return h
>
> -- catch the error with checkErr
> iter5 = do
>    (_,b)<-countBytes $ I.checkErr $ iter4
>    s <- I.stream2list
>    return (b,s)
>
> print5 = enumPure1Chunk [1..10] (iter5) >>= run >>= print
>
>
> Thanks a lot!
> Sergey
>
> 2011/6/2 John Lato <jwlato at gmail.com>:
> > Hi Sergey,
> >
> > I've got an explanation; quite surprisingly it's a bug in enumPure1Chunk.
> > Even though it is an odd case, I'm surprised that it hasn't come up
> before
> > now since enumPure1Chunk appears frequently.
> >
> > I've just uploaded 0.8.5.0 which has the fix.  There's now an additional
> > Monoid constraint on enumPure1Chunk, unfortunately.
> >
> > Thanks very much for reporting this.
> >
> > John L
> >
> > On Thu, Jun 2, 2011 at 10:02 AM, Sergey Mironov <ierton at gmail.com>
> wrote:
> >>
> >> Ok. I've checked iteratee-0.8.3.0 and 0.8.4.0. Results are same.
> >>
> >> Sergey
> >>
> >> 2011/6/2 John Lato <jwlato at gmail.com>:
> >> > Hi Sergey,
> >> > I can't explain this; maybe it's a bug in enumWith?  I'll look into
> it.
> >> > Thanks,
> >> > John
> >> >
> >> >>
> >> >> Message: 20
> >> >>
> >> >> Date: Thu, 2 Jun 2011 02:46:32 +0400
> >> >> From: Sergey Mironov <ierton at gmail.com>
> >> >> Subject: [Haskell-cafe] [iteratee] how to do nothing .. properly
> >> >> To: haskell-cafe at haskell.org
> >> >> Message-ID: <BANLkTimMFRWgH9Nopt-eua+L7jQcGq+u=g at mail.gmail.com>
> >> >> Content-Type: text/plain; charset=ISO-8859-1
> >> >>
> >> >> Hi. Would anybody explain a situation with iter6 and iter7 below?
> >> >> Strange thing - first one consumes no intput, while second consumes
> it
> >> >> all, while all the difference is peek  which should do no processing
> >> >> (just copy next item in stream and return to user).
> >> >> What I am trying to do - is to write an iteratee consuing no input,
> >> >> but returning a constant I give to it. I thought (return a) should do
> >> >> it, but it seems I was wrong as return actually consumes all unparsed
> >> >> stream. iter6 experience tells me that (peek>>return a) is what I
> >> >> need, but it's completely confusing and not what I expected.
> >> >>
> >> >> Thanks,
> >> >> Sergey
> >> >>
> >> >>  import Data.Iteratee as I
> >> >>  import Data.Iteratee.IO
> >> >>  import Control.Monad
> >> >>  import Control.Exception
> >> >>  import Data.ByteString
> >> >>  import Data.Char
> >> >>  import Data.String
> >> >>
> >> >>  -- countBytes :: (..., Num b) => Iteratee s m a -> Iteratee s m (a,
> b)
> >> >>  countBytes i = enumWith i I.length
> >> >>
> >> >>  iter6 = do
> >> >>     h <- countBytes $ (peek >> return 0)
> >> >>     s <- I.stream2list
> >> >>     return (h,s)
> >> >>
> >> >>  iter7 = do
> >> >>     h <- countBytes $ (return 0)
> >> >>     s <- I.stream2list
> >> >>     return (h,s)
> >> >>
> >> >>  print6 = enumPure1Chunk [1..10] (iter6) >>= run >>= print
> >> >>  print7 = enumPure1Chunk [1..10] (iter7) >>= run >>= print
> >> >>
> >> >>
> >> >> Here is example ghci session
> >> >>
> >> >> *Main> print6
> >> >> ((0,0),[1,2,3,4,5,6,7,8,9,10])
> >> >> -- read 0 items, returns 0
> >> >> *Main> print7
> >> >> ((0,10),[])
> >> >> -- read 10 items (???) returns 0
> >> >> *Main>
> >> >>
> >> >>
> >> >>
> >> >> ------------------------------
> >> >>
> >> >> _______________________________________________
> >> >> Haskell-Cafe mailing list
> >> >> Haskell-Cafe at haskell.org
> >> >> http://www.haskell.org/mailman/listinfo/haskell-cafe
> >> >>
> >> >>
> >> >> End of Haskell-Cafe Digest, Vol 94, Issue 3
> >> >> *******************************************
> >> >
> >> >
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20110605/8ea01330/attachment.htm>


More information about the Haskell-Cafe mailing list