实例声明上的模式匹配错误

时间:2013-02-14 16:22:04

标签: haskell instance monads

我需要为特定数据类型声明Monad实例:

data M m a = Mk (m (Maybe a))

instance (Monad m) => Monad (M m) where
  return x = Mk (m (Just x))
  Mk (m (Nothing)) >>= f = Mk (m (Nothing))
  Mk (m (Just x)) >>= f = f x

但我明白了:

test.hs:6:7: Parse error in pattern: m
Failed, modules loaded: none.

这可能很简单,但我无法弄明白!

2 个答案:

答案 0 :(得分:5)

类型变量m不是您可以模式匹配的内容,尤其不是为了区分JustNothing。考虑一下代替m使用的不同可能类型意味着什么 - 在很多情况下,这样的模式匹配是完全不可能的。

要编写该实例,您需要这样的内容:

instance (Monad m) => Monad (M m) where
  return x = Mk (return (Just x))
  Mk mx >>= f = -- ??

注意return用于创建类型m (Maybe a)的值 - 这可能是因为Monad m约束,并且在一般情况下(根本没有约束)' d无法创造这样的价值。

要实施(>>=),您需要执行类似操作,同样对(>>=) Monad m实例使用newtype

顺便说一句,您应该考虑使用M data,除非您有特定理由想要newtype。大多数情况下,如果你可以使用{{1}},你应该。

答案 1 :(得分:0)

您只能在构造函数上进行模式匹配,而不能在其他任何模式上进行匹配。你必须使用m的Monad实例来获取里面的Maybe数据。我不是百分之百确定这有你想要的行为,但确实存在类型问题。

data M m a = Mk (m (Maybe a))

instance (Monad m) => Monad (M m) where
  return x = Mk (return (Just x))
  Mk m >>= f = Mk (m >>= go)
    where go (Just x) = let Mk x' = f x in x'
          go _        = return Nothing