在haskell中定义新monad不会引发Applicative的实例
我正在尝试定义一个新的monad,并且出现一个奇怪的错误
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的实例?
这是适用性Monad方案(AMP)。 现在,无论何时您声明为Monad ,您也必须将其声明为Applicative (因此也称为Functor )。 从数学上讲,每个monad都是一个应用函子,所以这是有道理的。
您可以执行以下操作来删除该错误:
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版本会出现错误。 这是一个突破性的变化。
编辑:以下声明应该适用于任何monad:
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
根据所讨论的monad,可能会有更高效的实现,但这是一个简单的起点。
链接地址: http://www.djcxy.com/p/5679.html上一篇: Defining a new monad in haskell raises no instance for Applicative
