[Haskell-cafe] Re: Are there standard idioms for lazy, pure error handling?

Nicolas Pouillard nicolas.pouillard at gmail.com
Tue Dec 1 07:38:34 EST 2009


Excerpts from Heinrich Apfelmus's message of Tue Dec 01 11:29:24 +0100 2009:
> 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)

This proposition looks quite nice and gently subsume the ListThenError
type.

type ListThenError e a = Train a (Maybe e)

Anyone to put this on Hackage?

-- 
Nicolas Pouillard
http://nicolaspouillard.fr


More information about the Haskell-Cafe mailing list