Как показать, что монада является функтором и аппликативным функтором? - PullRequest
15 голосов
/ 01 февраля 2012

Монады, как известно, теоретически являются подмножеством функторов и, в частности, аппликативных функторов, хотя это не указано в системе типов Хаскелла.

Зная это, учитывая монаду и основываясь на return и bindкак:

  • получить fmap,
  • получить <*>?

Ответы [ 2 ]

26 голосов
/ 01 февраля 2012

Ну, fmap это просто (a -> b) -> f a -> f b, т.е. мы хотим преобразовать результат монадического действия с помощью чистой функции.Это легко написать с помощью нотации:

fmap f m = do
  a <- m
  return (f a)

или написано "raw":

fmap f m = m >>= \a -> return (f a)

Это доступно как Control.Monad.liftM.

pure :: a -> f a - это, конечно, return.(<*>) :: f (a -> b) -> f a -> f b немного сложнее.У нас есть действие, возвращающее функцию, и действие, возвращающее ее аргумент, и мы хотим, чтобы действие возвращало ее результат.Снова сделайте запись:

mf <*> mx = do
  f <- mf
  x <- mx
  return (f x)

Или, обессиленный:

mf <*> mx =
  mf >>= \f ->
  mx >>= \x ->
  return (f x)

Тада!Это доступно как Control.Monad.ap, поэтому мы можем дать полный экземпляр Functor и Applicative для любой монады M следующим образом:

instance Functor M where
  fmap = liftM

instance Applicative M where
  pure = return
  (<*>) = ap

В идеале, мысмог бы указать эти реализации непосредственно в Monad, чтобы облегчить бремя определения отдельных экземпляров для каждой монады, например, с этим предложением .Если это произойдет, не будет никаких реальных препятствий для того, чтобы сделать Applicative суперклассом Monad, так как он гарантирует, что он не сломает существующий код.С другой стороны, это означает, что шаблон, участвующий в определении Functor и Applicative экземпляров для данного Monad, минимален, поэтому легко быть «хорошим гражданином» (и такие экземпляры должны быть определены для любой монады).

10 голосов
/ 01 февраля 2012

fmap = liftM и (<*>) = ap.Вот ссылки на исходный код для liftM и ap .Я полагаю, вы знаете, как desugar делать обозначения.

...