2

我需要为特定数据类型声明一个 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.

这可能很简单,但我无法弄清楚!

4

2 回答 2

5

类型变量m不是您可以进行模式匹配的东西,尤其是不能区分Justand Nothing。想一想它对于代替-- 在m许多情况下使用的不同可能类型意味着什么,这样的模式匹配是完全不可能的。

要编写该实例,您需要以下内容:

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

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

要实现(>>=)你需要做一些类似的事情,(>>=)同样Monad使用m.

顺便说一句,您应该考虑使用newtypefor M,除非您有特定的需要data。大多数时候,如果你可以使用newtype,你应该。

于 2013-02-14T16:27:51.747 回答
0

您只能在构造函数上进行模式匹配,而不能在其他任何东西上进行模式匹配。您必须使用 m 的 Monad 实例才能访问其中的 Maybe 数据。我不是 100% 确定这是否具有您想要的行为,但它会进行类型检查。

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
于 2013-02-14T18:40:19.517 回答