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?
Extendis aComonadwithout 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 useExtendto represent it. I recommend Neighborhood of Infinity for an introduction to comonads by example.We have a similar thing for
MonadandApplicative, by the way.BindisMonadbut withoutreturn, andApplyisApplicativebut withoutpure. You can find both of these classes in the samesemigroupoidspackage you linked.As an example, nonempty lists form a comonad, with
duplicate = tailsandextract = head. Thenextend f = fmap f . duplicate. This is fine if we haveNonEmpty, but if the list might be empty,extract = headis no longer a total function. We still haveduplicateandextend, so[]can beExtendbut it can't beComonad. (Thanks @phadej for this example!)