
Duncan Coutts wrote:
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.
I propose to (trivially) generalize this type to "list with an end" data ListEnd a b = Cons a (ListEnd a b) | End b because it may have other uses than just lazy error handling. For mnemonic value, we could call it a "train": data Train a b = Wagon a (Train a b) | Loco b as it is in analogy with a sequence of wagons of the same type followed by the locomotive which has a different type. This data type naturally turns up as the differential of the lists d [x] = Train x [x] and the usual zipper ([x],[x]) is actually an optimization: Train a b == ([a] , b) Incidentally, this isomorphism corresponds to the alternative approach you mentioned:
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 }
As for other uses of Train , I remember seeing the following fold operation fold1 :: (a -> b -> b) -> (a -> b) -> [a] -> b fold1 f g [a] = g a foldl f g (a:x) = f a (fold1 f g x) (from Oege de Moor, Jeremy Gibbons. "Bridging the Algorithm Gap: A Linear-Time Functional Program for Paragraph Formatting" http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.47.3229 ) which is of course the natural fold for the Train data type: fold :: (a -> c -> c) -> (b -> c) -> Train a b -> c fold f g (Loco b) = g b fold f g (Wagon a t) = f a (fold f g t) Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com