Подтвердить что ты не робот

Определение новой монады в haskell не вызывает никакого экземпляра для аппликативного

Я пытаюсь определить новую монаду, и я получаю странную ошибку

newmonad.hs

newtype Wrapped a = Wrap {unwrap :: a}
instance Monad Wrapped where
  (>>=) (Wrap x) f =  f x
  return x = Wrap x

main = do
  putStrLn "yay"
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.10.1

$ ghc newmonad.hs 
[1 of 1] Compiling Main             ( newmonad.hs, newmonad.o )

newmonad.hs:2:10:
    No instance for (Applicative Wrapped)
      arising from the superclasses of an instance declaration
    In the instance declaration for ‘Monad Wrapped’

Почему мне нужно определить экземпляр Applicative?

4b9b3361

Ответ 1

Это аппликативное предложение Монады (AMP). Теперь, когда вы объявляете что-то как Monad, вы также должны объявить его как Applicative (и, следовательно, Functor). Математически каждая монада является прикладным функтором, поэтому это имеет смысл.

Вы можете сделать следующее, чтобы удалить ошибку:

instance Functor Wrap where
  fmap f (Wrap x) = Wrap (f x)

instance Applicative Wrap where
  pure = Wrap
  Wrap f <*> Wrap x = Wrap (f x)

https://wiki.haskell.org/Functor-Applicative-Monad_Proposal

Изменить: Возможно, я должен более четко указать, что это последнее дело? Ранее используемый вами код использовался, но с последними версиями GHC вы получите сообщение об ошибке. Это потрясающее изменение.

Изменить: Следующие объявления должны работать для любой монады:

import Control.Applicative -- Otherwise you can't do the Applicative instance.
import Control.Monad (liftM, ap)

instance Functor ??? where
  fmap = liftM

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

В зависимости от рассматриваемой монады возможны более эффективные реализации, но это простая отправная точка.