
On Mon, 2009-11-30 at 06:08 +0000, Malcolm Wallace wrote:
However, if you really want to terminate the stream at the first error, and to reflect this in the type, then I guess you can define your own list type:
data ListThenError e a = Cons a (ListThenError e a) | Error e
Of course this has the disadvantage that then your consumer must change to use this type too.
I've been using this list type quite a lot recently. It's in the 'tar' package for example. It comes with variants of the standard functions foldl, foldr, unfoldr that take into account the error possibility. At some point we should probably make a package to standardise and document this lazy error handling idiom. Another approach that some people have advocated as a general purpose solution is to use: data Exceptional e a = Exceptional { exception :: Maybe e result :: a } However it's pretty clear from the structure of this type that it cannot cope with lazy error handling in sequences. If you try it you'll find you cannot do it without space leaks. Adding the errors directly into the structure seems the best approach to me. It means the data structure directly reflects the unfolding of the various possibilities, including errors. It also makes the strictness of operations much easier to understand. Then we just have to be comfortable manipulating these data structures using the appropriate folds and unfolds. Classic pure lazy FP. Duncan