instance Monoid m => Applicative (Const m) where
pure _ = Const mempty
Const f <*> Const v = Const (f `mappend` v)
I do not understand how can the definition of <*>
type-check.
On the left side f
is constrained by the signature of <*>
as in the definition of Applicative
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
After changing the names to the current situation:
(<*>) :: c (m -> b) -> c m -> c b
=> f :: m -> *
.
On the left side f
is the [first] parameter of mappend
.
From the definition of Monoid
class Monoid a where
mempty :: a
-- ^ Identity of 'mappend'
mappend :: a -> a -> a
After changing the names to the current situation:
mappend :: m -> m -> m
=> f :: m
.
(<*>) :: f (a->b) -> f a -> f b
≡ (Const m) (a->b) -> (Const m) a -> (Const m) b
≡ Const m (a->b) -> Const m a -> Const m b
≅ m -> m -> m
which is the signature of <>
(aka mappend
).
After changing the names to the current situation:
(<*>) :: c (m -> b) -> c m -> c b
=>
f :: m -> *
.
Not quite. After changing the names to the current situation:
(<*>) :: Const m (a -> b) -> Const m a -> Const m b
Since a value of type Const x y
is the constructor Const
applied to a value of type x
, this means f :: m
(and v :: m
), and we know Monoid m
from the instance context.
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