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