在Monad定义中键入错误

时间:2014-06-15 19:23:54

标签: haskell monads

我正在努力了解Haskell中的Monads。 鉴于数据类型:

data XY a = X a | Y a

我希望'X a >>= f'返回'f a''Y a >>= f',忽略'f'并返回'Y a'

这是我写的代码:

  4 instance Monad XY where
  5         return x = X x
  6         (X a) >>= f = f a
  7         (Y a) >>= f = Y a

这是我得到的编译器错误:

prog.hs:7:25:
    Couldn't match expected type `b' with actual type `a'
      `b' is a rigid type variable bound by
          the type signature for >>= :: XY a -> (a -> XY b) -> XY b
          at prog.hs:6:9
      `a' is a rigid type variable bound by
          the type signature for >>= :: XY a -> (a -> XY b) -> XY b
          at prog.hs:6:9
    In the first argument of `Y', namely `a'
    In the expression: Y a
    In an equation for `>>=': (Y a) >>= f = Y a
Failed, modules loaded: none.

你能帮我理解我错过的东西吗?

1 个答案:

答案 0 :(得分:9)

考虑>>=的类型:

(>>=) :: XY a -> (a -> XY b) -> XY b

根据Y a >>= f的个案,您将返回XY a,而不是XY b。这就是为什么类型错误告诉您它无法与预期的b与实际a匹配。

一般来说,您尝试做的事情(始终返回Y a)没有意义,因为XY只有一个类型参数,如果不更改值{{}},则无法更改1}}。看看Monad instance for Either,看看如何通过稍微不同的类型来完成这种事情。