正确定义monad类

时间:2017-01-08 11:19:30

标签: haskell monads

如何使列表monad的以下声明可编辑?

module Main where

instance Monad m where
  -- "return" constructs a one-item list.
  return x = [x]
  -- "bind" concatenates the lists obtained by applying f to each item in list xs.
  xs >>= f = concat (map f xs)
  -- The zero object is an empty list.
  mzero = []

目前我收到以下错误:

monad_ex1.hs:9:3: ‘mzero’ is not a (visible) method of class ‘Monad’

我的代码来自https://en.wikipedia.org/wiki/Monad_(functional_programming)#Collections,目标是从中运行创建可编译代码,将其导入ghci并使用它。

从代码中删除mzero会导致另一条神秘的消息:

Illegal instance declaration for ‘Monad m’
      (All instance types must be of the form (T a1 ... an)
       where a1 ... an are *distinct type variables*,
       and each type variable appears at most once in the instance head.
       Use FlexibleInstances if you want to disable this.)
    In the instance declaration for ‘Monad m’

1 个答案:

答案 0 :(得分:3)

这里有一些潜在的陷阱,其中大部分都包含在评论中:

  • mzero个实例没有定义Monad,如果您尝试指定一个,则会出错。 mzero将在MonadPlus实例中定义,如果有的话。{/ li>
  • 尝试重新定义内置列表的monad实例将不起作用。如果你想玩这个,你需要定义自己的List类型。
  • 在“现代”Haskell中(自GHC 7.10起),Applicative => Monad Proposal的实现已经淘汰了许多旧的Monad教程,并使用户定义的Monads更难编写,因为您还需要定义{ {1}}和Functor个实例(detailed migration instructions)。

因此,这里是您的列表示例的翻译,以使用具有GHC 7.10兼容样板的用户定义的Applicative类型。请注意,List的定义会转移到return实例的Applicative中。

pure