This repository contains bits and pieces of Haskell code written for my own amusement.


Further references


On the comonad interface from ConorMcBride:

  • extract means "give element here"
  • duplicate means "decorate each element with its context"

On the Store comonad from Russel O'Connor:

Given the following definition of store,

data Store s a = Store { peek :: s -> a, pos :: s }

I like to think of a Store as a big warehouse filled with values of type a. Each value of type a is slotted into a position labeled by an index value of type s. Finally there is a forklift parked at position pos. The forklift can be used to extract a value of type a from the store by pulling the value out from where it is parked. You can use seek to move the forklift to a new absolute position or use seeks to move the forklift to a new relative location. To update all values of the store use fmap. Finally extend f is similar to fmap except instead of f :: a -> a' we have f :: Store s a -> a' which lets the update function not only have access to the value being updated but also gives access to the value's position and access to the values of everything else in the store. In other words, extend uses the value plus its surrounding context to perform the update.

Abstracting over functor shape. The same functor can be represented in multiple ways by changing the constructors' name. However, I would like to be able to reuse functions when functors have the same shape. Let's take as an example the functor, F(X) = 1 + X; it can be encoded in the following ways:

data MyEither a   = Left () | Right a
data NatF     a   = ZeroF   | SuccF a
data ListF    a b = NilF    | ConsF a b  -- assuming we fix `a`

I would like the cofork functions to work on all those type, without have to specify it for each instance separately:

coforkMyEither :: ((() -> c), (a      -> c)) -> MyEither a   -> c
coforkNatF     :: ((() -> c), (a      -> c)) -> NatF     a   -> c
coforkListF    :: ((() -> c), ((a, b) -> c)) -> ListF    a b -> c