Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Applicative implementation of Const Monoid

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.

like image 451
libeako Avatar asked Dec 19 '22 22:12

libeako


2 Answers

(<*>) :: 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).

like image 116
leftaroundabout Avatar answered Dec 28 '22 14:12

leftaroundabout


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.

like image 32
Daniel Wagner Avatar answered Dec 28 '22 14:12

Daniel Wagner