我正在尝试定义一个新的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
的实例?
答案 0 :(得分:79)
这是适用的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,可能会有更高效的实现,但这是一个简单的起点。
答案 1 :(得分:1)
最规范,最简单的答案是:-
因为Monad依赖于应用性
class Applicative m => Monad m其中...
而Applicative取决于Functor
类Functor f =>适用于f,其中...
我们需要实例定义
> instance Functor Wrapped where
> fmap = liftM
和
> instance Applicative Wrapped where
> pure = return
> (<*>) = ap