[Haskell-cafe] snoc vs cons

Derek Elkins derek.a.elkins at gmail.com
Wed Jul 25 12:44:13 EDT 2007

On Wed, 2007-07-25 at 11:37 +0100, Conor McBride wrote:
> Hi folks
> Scary word warning: Monoid, Monad, Applicative, Traversable, Context,
>    Cursor
> > Eric:
> >> Does anyone know of a good article which discusses snoc vs cons  
> >> lists?
> Derek:
> > There's no reason to; there is no difference between a snoc list and a
> > cons list.
> There's no technical reason to, but sometimes there are human factors.
> Basically, I want the lists in my code to resemble the lists in my head.
> I occasionally implement typecheckers, and it's traditional to present
> the context as growing on the right as you peel off binders from the
> left: I prefer to use snoc-lists for them. Keeping the code consistent
> with the mental picture means I seldom need to think about which things
> are in scope of what, and so on. I make fewer reverse-parity mistakes.
> Amongst my standard equipment, I keep
>    data Fwd x = F0 | x :> Fwd x
>    data Bwd x = B0 | Bwd x :< x
> They're both monoids by concatenation, and Applicative with the
> zipping behaviour, ie, not the ap of the [] monad, or any other monad
> for that matter.
> They're both Traversable, left-to-right, and that makes them really
> different:
>    traverse f (x :> xs)   does the effects of   (f x)   first;
>    traverse f (xs :< x)   does the effects of   (f x)   last.
> If I'm representing a cursor in a list, I use (Bwd x, Fwd x), or better,
> Prod Bwd Fwd x where
>    data Prod f g x = f x :*: g x
>    type Cursor = Prod Bwd Fwd
> so that I keep the left-to-right ordering, as well as fastest access  
> to the
> elements nearest the cursor.
> As Prod lifts monoids and preserves applicative structure, I get the
> zipping structure of cursor and the splicing-in-the-middle monoid for  
> free.
> This is yet another example of a type being not only a data  
> representation,
> but also a way of organising the structure of computations over that  
> data.
> Or in soundbitese... types don't just contain data, types explain data.

I heartily agree with all that (and especially that last line is a
large part of why I value static typing and see it as providing
something dynamic typing doesn't). One way saying snoc lists are the
same as cons lists is by saying that you simply change your point of
view on cons lists to one where the first element is the "end".  Of
course, such distinctions can and often should be made by the type

More information about the Haskell-Cafe mailing list