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