在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

下一篇: Techniques for Tracing Constraints