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'll crawl back under my rock now.
Cheers
Conor