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?
What's a typeclass in Haskell? A typeclass defines a set of methods that is shared across multiple types. For a type to belong to a typeclass, it needs to implement the methods of that typeclass. These implementations are ad-hoc: methods can have different implementations for different types.
A polymorphic function is called overloaded if its type contains one or more class constraints. (+) :: Num a ⇒ a -> a -> a. For any numeric type a, (+) takes two values of type a and returns a value of type a.
We say that Eq is a superclass of Ord (conversely, Ord is a subclass of Eq), and any type which is an instance of Ord must also be an instance of Eq. (In the next Section we give a fuller definition of Ord taken from the Prelude.)
An instance of a class is an individual object which belongs to that class. In Haskell, the class system is (roughly speaking) a way to group similar types. (This is the reason we call them "type classes"). An instance of a class is an individual type which belongs to that class.
Extend is a Comonad without the ability to extract. 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 use Extend to represent it. I recommend Neighborhood of Infinity for an introduction to comonads by example.
We have a similar thing for Monad and Applicative, by the way. Bind is Monad but without return, and Apply is Applicative but without pure. You can find both of these classes in the same semigroupoids package you linked.
As an example, nonempty lists form a comonad, with duplicate = tails and extract = head. Then extend f = fmap f . duplicate. This is fine if we have NonEmpty, but if the list might be empty, extract = head is no longer a total function. We still have duplicate and extend, so [] can be Extend but it can't be Comonad. (Thanks @phadej for this example!)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With