Аппликативная реализация Const Monoid

instance Monoid m => Applicative (Const m) where
    pure _ = Const mempty
    Const f <*> Const v = Const (f `mappend` v)

Я не понимаю, как определение типа <*> может проверять тип.

С левой стороны f ограничивается подписью <*>, как в определении Applicative

class Functor f => Applicative f where
    pure :: a -> f a
    (<*>) :: f (a -> b) -> f a -> f b

После изменения имен на текущую ситуацию:

    (<*>) :: c (m -> b) -> c m -> c b

=> f :: m -> *.

С левой стороны f — это [первый] параметр mappend.

Из определения моноида

class Monoid a where
        mempty  :: a
        -- ^ Identity of 'mappend'
        mappend :: a -> a -> a

После изменения имен на текущую ситуацию:

        mappend :: m -> m -> m

=> f :: m.


person libeako    schedule 23.11.2015    source источник


Ответы (2)


После изменения имен на текущую ситуацию:

(<*>) :: c (m -> b) -> c m -> c b

=> f :: m -> *.

Не совсем. После изменения имен на текущую ситуацию:

(<*>) :: Const m (a -> b) -> Const m a -> Const m b

Поскольку значение типа Const x y является конструктором Const, примененным к значению типа x, это означает f :: mv :: m), а Monoid m мы знаем из контекста экземпляра.

person Daniel Wagner    schedule 23.11.2015

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

что является подписью <> (он же mappend).

person leftaroundabout    schedule 23.11.2015