`(<$)`

.
]]>`(<$) = fmap . const`

, so the above:
`pure a = fmap (const a) units`

Can be written:

`pure a = a <$ units`

or:

`pure = (<$ units)`

We should realy invent a name for this pattern where we have a “type level datatype” (like Z and S n), an isomorphic value level GADT (like Nat) and a class that provides an overloaded constructor for this GADT (like IsNat).

I used this same pattern in 3 places already:

- http://hackage.haskell.org/packages/archive/explicit-iomodes/0.6.0.2/doc/html/System-IO-ExplicitIOModes.html#t:MkIOMode
- http://hackage.haskell.org/packages/archive/usb-safe/0.11.0.2/doc/html/System-USB-Safe.html#t:MkTransferDirection
- http://hackage.haskell.org/packages/archive/usb-safe/0.11.0.2/doc/html/System-USB-Safe.html#t:MkTransferType

I’m even thinking about using some CPP hackery to abstract the pattern.

]]>data Nat = Z | S Nat -- automatically lifted to the type/kind level! data Vec :: Nat -> * -> * where ZVec :: Vec Z a (:<) :: a -> Vec n a -> Vec (S n) a class Pure n where pureN :: a -> Vec n a instance Pure Z where pureN a = ZVec instance Pure (S n) where pureN a = a :< pureN a instance Applicative (Vec n) where pure a = pureN a ZVec <*> ZVec = ZVec (f :< fs) <*> (x :< xs) = f x :< (fs <*> xs)

Or something like that

]]>`Applicative`

instance above:
`instance Applicative (Vec Z) where`

pure _ = ZVec

ZVec ⊛ ZVec = ZVec

instance Applicative (Vec n) ⇒ Applicative (Vec (S n)) where

pure a = a :< pure a

(f :< fs) ⊛ (a :< as) = f a :< (fs ⊛ as)

I hadn’t considered splitting the one instance into two. I like the simplicity of this solution, though I suspect the constraint `Applicative (Vec n)`

would be cumbersome in practice. A small drawback of this version is that it requires the GHC language extensions `FlexibleInstances`

and `FlexibleContexts`

.

Continuing on to `Monad`

:

`instance Monad (Vec Z) where`

return = pure

v >>= f = joinZ (fmap f v)

instance Monad (Vec n) ⇒ Monad (Vec (S n)) where

return = pure

v >>= f = joinS (fmap f v)

`joinZ ∷ Vec Z (Vec Z a) → Vec Z a`

joinZ ZVec = ZVec

joinS ∷ Monad (Vec n) ⇒ Vec (S n) (Vec (S n) a) → Vec (S n) a

joinS (v :< vs) = headV v :< join (fmap tailV vs)

In this case, I'm using the general `join`

function on monads. The `Monad`

instances would be more elegant and perhaps more efficient if `join`

were a method on `Monad`

as has been proposed.