在 haskell 中定义一个新的 monad 不会引发 Applicative 的实例 [英] Defining a new monad in haskell raises no instance for Applicative
问题描述
我正在尝试定义一个新的 monad,但遇到一个奇怪的错误
newmonad.hs
<前>newtype Wrapped a = Wrap {unwrap :: a}实例 Monad Wrapped where(>>=) (Wrap x) f = f x返回 x = 包装 x主要 = 做putStrLn "耶"<前>$ ghc --versionGlorious Glasgow Haskell 编译系统,版本 7.10.1$ ghc newmonad.hs[1 of 1] 编译 Main ( newmonad.hs, newmonad.o )newmonad.hs:2:10:没有(Applicative Wrapped)的实例由实例声明的超类产生在ÄòMonad Wrapped"的实例声明中
为什么我需要定义一个Applicative
的实例?
这是 Applicative Monad Proposal (AMP).现在,每当你将某事物声明为 Monad
时,你还必须将其声明为 Applicative
(因此也是 Functor
).从数学上讲,每个 monad 都是一个应用函子,所以这是有道理的.
您可以执行以下操作来消除错误:
instance Functor Wrap wherefmap f (Wrap x) = Wrap (f x)实例 Applicative Wrap where纯 = 包裹包裹 f <*>包裹 x = 包裹 (f x)
https://wiki.haskell.org/Functor-Applicative-Monad_Proposal
也许我应该更清楚地指出这是最近的事情?您发布的代码以前可以使用,但是使用最近 版本的 GHC,您会收到错误消息.这是一个突破性的变化.
以下声明应该适用于任何 monad:
import Control.Applicative -- 否则不能做 Applicative 实例.导入 Control.Monad (liftM, ap)实例函子???在哪里fmap =liftM实例 适用 ???在哪里纯 = 回报(<*>) = ap
根据所讨论的 monad,可能有更高效的实现,但这是一个简单的起点.
I am trying to define a new monad and I am getting a strange error
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’
Why do I need to define an instance of Applicative
?
This is the Applicative Monad Proposal (AMP). Now whenever you declare something as Monad
, you also have to declare it as Applicative
(and therefore Functor
). Mathematically speaking, every monad is an applicative functor, so this makes sense.
You can do the following to remove the 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
Edit: Maybe I should point out more clearly that this is a recent thing? The code you posted used to work before, but with recent versions of GHC you'll get an error. It's a breaking change.
Edit: The following declarations should work for any 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
Depending on the monad in question, there may be more efficient implementations possible, but this is a simple starting point.
这篇关于在 haskell 中定义一个新的 monad 不会引发 Applicative 的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!