Re: [Haskell] Re: [Haskell-cafe] ANNOUNCE: enumerator, an alternative iteratee package

On Sat, Aug 21, 2010 at 23:14, Paulo Tanimoto
One question: enumFile has type
enumFile :: FilePath -> Enumerator SomeException ByteString IO b
and iterParser has type
iterParser :: Monad m => Parser a -> Iteratee ParseError ByteString m a
How do we use both together? Something in these lines won't type-check
E.run (E.enumFile "file" E.$$ (E.iterParser p))
because the error types are different.
Forgot to mention that -- use the "mapError" function from enumerator-0.2.1 thusly: http://ianen.org/haskell/enumerator/api-docs/Data-Enumerator.html#v%3AmapErr... -------------------------------------------------------------------------------- parser :: Parser Foo toExc :: Show a => a -> E.SomeException toExc = E.SomeException . E.ErrorCall . show main :: IO () main = do run (enumFile "parsetest.txt" $$ mapError toExc $$ iterParser parser) >>= print -------------------------------------------------------------------------------- You don't have to map to SomeException -- any type will do. For example, in a complex pipeline with real error handling at the other end, you might want a custom error type so you'll know at what stage the error occurred.

After fielding some more questions regarding error handling, it turns out that my earlier mail was in error (hah) -- error handling is much more complicated than I thought. When I gave each iteratee its own error type, I was expecting that each pipeline would have only one or two sources of errors -- for example. a parser, or a file reader. However, in reality, it's likely that every single element in a pipeline can produce an error. For example, in a JSON/XML/etc reformatter (enumFile, parseEvents, formatEvents, iterFile), errors could be SomeException, ParseError, or FormatError. Futhermore, while it's easy to change an iteratee's error type with just (e1 -> e2), changing an enumerator or enumeratee *also* requires (e2 -> e1). In other words, to avoid loss of error information, the two types have to be basically the same thing anyway. I would like to avoid hard-coding the error type to SomeException, because it forces libraries to use unsafe/unportable language features (dynamic typing and casting). However, given the apparent practical requirement that all iteratees have the same error type, it seems like there's no other choice. So, my questions: 1. Has anybody here successfully created / used / heard of an iteratee implementation with independent error types? 2. Do alternative Haskell implementations (JHC, UHC, Hugs, etc) support DeriveDataTypeable? If not, is there any more portable way to define exceptions? 3. Has anybody actually written any libraries which use the existing "enumerator" error handling API? I don't mind rewriting my own uploads, since this whole mess is my own damn fault, but I don't want to inconvenience anybody else.

It's not released yet, but persistent 0.2 is going to be using enumerator. I
personally don't mind SomeException as a hard-coded error type, but go ahead
and do whatever you think is best for the API.
Michael
On Tue, Aug 24, 2010 at 5:47 AM, John Millikin
After fielding some more questions regarding error handling, it turns out that my earlier mail was in error (hah) -- error handling is much more complicated than I thought.
When I gave each iteratee its own error type, I was expecting that each pipeline would have only one or two sources of errors -- for example. a parser, or a file reader. However, in reality, it's likely that every single element in a pipeline can produce an error. For example, in a JSON/XML/etc reformatter (enumFile, parseEvents, formatEvents, iterFile), errors could be SomeException, ParseError, or FormatError.
Futhermore, while it's easy to change an iteratee's error type with just (e1 -> e2), changing an enumerator or enumeratee *also* requires (e2 -> e1). In other words, to avoid loss of error information, the two types have to be basically the same thing anyway.
I would like to avoid hard-coding the error type to SomeException, because it forces libraries to use unsafe/unportable language features (dynamic typing and casting). However, given the apparent practical requirement that all iteratees have the same error type, it seems like there's no other choice.
So, my questions:
1. Has anybody here successfully created / used / heard of an iteratee implementation with independent error types? 2. Do alternative Haskell implementations (JHC, UHC, Hugs, etc) support DeriveDataTypeable? If not, is there any more portable way to define exceptions? 3. Has anybody actually written any libraries which use the existing "enumerator" error handling API? I don't mind rewriting my own uploads, since this whole mess is my own damn fault, but I don't want to inconvenience anybody else. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 24/08/10 03:47, John Millikin wrote: [...]
I would like to avoid hard-coding the error type to SomeException, because it forces libraries to use unsafe/unportable language features (dynamic typing and casting). However, given the apparent practical requirement that all iteratees have the same error type, it seems like there's no other choice.
I haven't worked enough with iteratees to have an informed opinion on this, but I wonder what the pros and cons are of having an error state in the iteratees at all. In other words, why would this data Step a m b = Continue (Stream a -> Iteratee a m b) | Yield b (Stream a) | Error E.SomeException be preferred over this data Step a m b = Continue (Stream a -> Iteratee a m b) | Yield b (Stream a) (Maybe with the restriction that m is a MonadError.) /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus@therning.org http://therning.org/magnus identi.ca|twitter: magthe
participants (3)
-
John Millikin
-
Magnus Therning
-
Michael Snoyman