在haskell中定义新monad不会引发Applicative的实例 [英] Defining a new monad in haskell raises no instance for Applicative

查看:211
本文介绍了在haskell中定义新monad不会引发Applicative的实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图定义一个新的monad,并且出现一个奇怪的错误。

newmonad.hs

 
newtype Wrapped a = Wrap {unwrap :: a}
实例Monad Wrapped其中
(>> =)(Wrap x)f = fx
return x = Wrap x

main = do
putStrLnyay



 $ ghc --version 
Glorious Glasgow Haskell编译系统,版本7.10.1

$ ghc newmonad.hs
[编译] Main(newmonad.hs,newmonad.o)

newmonad.hs:2:10:
从实例声明的超类产生的(Applicative Wrapped)
没有实例
在实例声明中,为什么需要定义一个的实例?为什么需要定义一个的实例? Applicative

解决方案

这是Applicative Monad Proposal(AMP)。现在,无论何时声明 Monad ,您还必须声明它为 Applicative (因此函子)。从数学上讲,每个monad 都是一个应用函数,所以这是有道理的。



您可以执行以下操作来删除错误:

 实例Functor Wrap其中
fmap f(Wrap x)= Wrap(fx)

实例换行
pure =换行
换行f * Wrap x = Wrap(fx)

https://wiki.haskell.org/Functor-Applicative-Monad_Proposal



编辑:也许我应该更清楚地指出这是一件最近的事情?您发布的代码之前曾经使用过,但是使用最近的 GHC版本,您将会遇到错误。这是一个重大改变。



编辑:以下声明适用于任何 monad:

  import Control.Applicative  - 否则您无法执行Applicative实例。 
导入Control.Monad(liftM,ap)

实例Functor ???其中
fmap = liftM

实例应用?其中
pure =返回
(*)= 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆