在haskell中定义一个新monad不会引发Applicative的实例
我正在尝试定义一个新的monad,并且出现一个奇怪的错误
newmonad.hs
新types包装a =包装{unwrap :: a} 实例Monad包裹在哪里 (>> =)(Wrap x)f = fx 返回x =包装x main = do putStrLn“耶”
$ ghc --version Glorious Glasgow Haskell编译系统,版本7.10.1 $ ghc newmonad.hs [1的1]编译主(newmonad.hs,newmonad.o) newmonad.hs:2:10: 没有适用于(应用包装)的实例 来自实例声明的超类 在“Monon Wrapped”的实例声明中
为什么我需要定义一个Applicative
实例?
这是适用的Monadscheme(AMP)。 现在每当你声明Monad
,你也必须把它声明为Applicative
(也就是Functor
)。 从math上讲,每个monad 都是一个应用函数,所以这是有道理的。
您可以执行以下操作来删除错误:
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
编辑:也许我应该更清楚地指出,这是最近的事情? 您发布的代码以前曾经工作过,但是最近的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,可能会有更高效的实现,但这是一个简单的起点。