Définir une nouvelle monade dans haskell ne déclenche aucune instance pour Applicative

J’essaie de définir une nouvelle monade et je reçois une erreur étrange

newmonad.hs

 newtype Wrapped a = Wrap {unwrap :: a}
 exemple Monad Wrapped où
   (>> =) (Wrap x) f = fx
   return x = Wrap x

 main = do
   putStrLn "yay"
 $ ghc --version
 Le système de compilation Glorious Glasgow Haskell, version 7.10.1

 $ ghc newmonad.hs 
 [1 sur 1] Comstackr Main (newmonad.hs, newmonad.o)

 newmonad.hs: 2: 10:
     Aucune instance pour (Applicatif Wrapped)
       provenant des superclasses d'une déclaration d'instance
     Dans la déclaration d'instance pour «Monad Wrapped»

Pourquoi dois-je définir une instance de Applicative ?

Ceci est la proposition de monade applicative (AMP). Maintenant, chaque fois que vous déclarez quelque chose comme Monad , vous devez également le déclarer comme Applicative (et donc Functor ). Mathématiquement parlant, chaque monade est un foncteur applicatif, donc cela a du sens.

Vous pouvez effectuer les opérations suivantes pour supprimer l’erreur:

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

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

Edit: Peut être que je devrais souligner plus clairement que c’est une chose récente ? Le code que vous avez posté fonctionnait auparavant, mais avec les versions récentes de GHC, vous obtenez une erreur. C’est un changement de rupture.

Edit: Les déclarations suivantes devraient fonctionner pour n’importe quelle monade:

 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 

Selon la monade en question, il peut y avoir des implémentations plus efficaces, mais c’est un sharepoint départ simple.

La réponse la plus normalisée et la plus discrète est: –

comme Monad dépend de l’application

classe Applicable m => Monad m où …

et applicative dépend de Functor

class Functor f => Applicatif f où …

nous avons besoin des définitions d’instance

 > instance Functor Wrapped where > fmap = liftM 

et

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