简体   繁体   English

在 haskell 中定义一个新的 monad 不会引发 Applicative 的实例

[英]Defining a new monad in haskell raises no instance for Applicative

I am trying to define a new monad and I am getting a strange error我正在尝试定义一个新的 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’

Why do I need to define an instance of Applicative ?为什么我需要定义Applicative的实例?

This is the Applicative Monad Proposal (AMP). 这是适用的Monad提案(AMP)。 Now whenever you declare something as Monad , you also have to declare it as Applicative (and therefore Functor ). 现在,每当您将某物声明为Monad ,还必须将其声明为Applicative (因此也要声明为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 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. 您发布的代码以前曾经可以使用,但是在GHC的最新版本中,您会得到一个错误。 It's a breaking change. 这是一个巨大的变化。

Edit: The following declarations should work for any monad: 编辑:以下声明应适用于任何 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. 根据所讨论的monad,可能会有更有效的实现方式,但这只是一个简单的起点。

The most normalized and unobtrusive answer is :- 最规范,最简单的答案是:

as Monad is dependent upon Applicative 因为Monad取决于Applicative

class Applicative m => Monad m where ... class Applicative m => Monad m其中...

and Applicative is dependent upon Functor 而Applicative取决于Functor

class Functor f => Applicative f where ... 类Functor f =>适用的f其中...

we need the instance definitions 我们需要实例定义

> instance Functor Wrapped where
>     fmap = liftM

and

> instance Applicative Wrapped where
>     pure = return
>     (<*>) = ap

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM