A pointed container is a comonad, and this observation can be used to obtain some useful effects, like for example stencil convolutions, almost for free. Further it is noticed that an instance Comonad
may be obtained in a standard way via the Store comonad (by the means of a partially applied index function), and it would work just as fine as a hand-written definition.
But this approach has a drawback: Store is essentially a function, and once something is made into a function, going back is uncomfortable. And I notice there are situations such that a small change in requirements requires one to completely abandon the notion of a comonad, and return to the consideration of the initial container. I find it similar to final tagless evaluation: local transformations are easy, but the more context they require, the more complicated it gets. One may recover any portion of the initial container by iterating extraction over the corresponding subset of the cursor space, but then why trade the initial type for the final in the first place?
In other words, there are 2 ways to represent a container, and both are equally conducive to the definition of instance Comonad
:
- As an "initial" data type. Without Dependent Types, the trivial definition of
instance Comonad
in Haskell, when a container is paired with an index, is partial (index may point to a place outside the shape of the container), but it will still work. - As a "final" partially applied index function. A container may be made into a comonad by wrapping it in
Store
. It is then paired with an index automagically. Partiality argument applies equally, so there is no safety to be gained.
When the initial type is traded for the final function, all the methods defined for the initial type are lost until recovered with more or less elaboration. Given that access to a small finite container is unsafe (most indices are undefined), and that the container itself is not accessible to query, programming becomes a game of minesweeper. Whatever properties of the initial container I have not providently put in an EnvT
, are lost. All in all, whatever safety or convenience benefit Store
is supposed to give is contested by the hardships of handling a final representation of a container.
Put more concisely, a pointed container is, among other things, a comonad, but Store is only a comonad.
So, what is the motivation for Store
? And can we get an instance Comonad
, or at least Extend
, more cheaply?