traduccion - Definir una nueva mónada en Haskell no plantea instancias para Applicative
monads learn you a haskell (2)
Esta es la Propuesta Aplicativa de Mónada (AMP).
Ahora, cada vez que declares algo como
Monad
, también debes declararlo como
Applicative
(y, por lo tanto,
Functor
).
Matemáticamente hablando, cada mónada
es
un funtor aplicativo, por lo que esto tiene sentido.
Puede hacer lo siguiente para eliminar el error:
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
Editar: ¿ Quizás debería señalar más claramente que esto es algo reciente ? El código que publicó solía funcionar antes, pero con las versiones recientes de GHC obtendrá un error. Es un cambio radical.
Editar: Las siguientes declaraciones deberían funcionar para cualquier mónada:
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
Dependiendo de la mónada en cuestión, puede haber implementaciones más eficientes posibles, pero este es un punto de partida simple.
Estoy tratando de definir una nueva mónada y recibo un error extraño
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’
¿Por qué necesito definir una instancia de
Applicative
?
La respuesta más normalizada y discreta es: -
como Monad depende del aplicativo
clase Aplicativo m => Mónada m donde ...
y aplicativo depende de Functor
class Functor f => Aplicativo f donde ...
necesitamos las definiciones de instancia
> instance Functor Wrapped where
> fmap = liftM
y
> instance Applicative Wrapped where
> pure = return
> (<*>) = ap