In Haskell, there is a type class called Extend.
The class is defined as the following
class Functor w => Extend w where
extended :: (w a -> b) -> w a -> w b
Every instance of the Extend
class should have the following properties:
extended f . extended g = extended (f . extended g)
I can see its similarities to Functor
. Particularly, Functor
's property fmap f . fmap g == fmap (f . g)
looks similar to Extend
.
How would you interpret Extend
? What is the significance of it? Does it make any computations easier? What abstractions are made when using Extend
?
Extend
is aComonad
without the ability toextract
. It's an "almost comonad", if you want to think of it like that. It's probably more helpful to ask the question "what is the meaning of comonads". Then, when you find something that's almost a comonad, you know you can useExtend
to represent it. I recommend Neighborhood of Infinity for an introduction to comonads by example.We have a similar thing for
Monad
andApplicative
, by the way.Bind
isMonad
but withoutreturn
, andApply
isApplicative
but withoutpure
. You can find both of these classes in the samesemigroupoids
package you linked.As an example, nonempty lists form a comonad, with
duplicate = tails
andextract = head
. Thenextend f = fmap f . duplicate
. This is fine if we haveNonEmpty
, but if the list might be empty,extract = head
is no longer a total function. We still haveduplicate
andextend
, so[]
can beExtend
but it can't beComonad
. (Thanks @phadej for this example!)