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

Haskell 实例声明上的模式匹配错误,haskell,instance,monads,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 patte

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

这可能很简单,但我想不出来

类型变量
m
不是您可以进行模式匹配的对象,尤其不是为了区分
Just
Nothing
。想想它对于替代
m
的不同可能类型意味着什么——在许多情况下,这样的模式匹配是完全不可能的

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

instance (Monad m) => Monad (M m) where
  return x = Mk (return (Just x))
  Mk mx >>= f = -- ??
请注意,用于创建类型为
m(可能是a)
的值的
return
——这是可能的,因为
Monad m
约束,在一般情况下(根本没有约束),无法创建这样的值

要实现
(>>=)
您需要做一些类似的事情,同样地,对
m
Monad
实例使用
(>>=)


顺便说一下,您应该考虑使用< <代码> NeXyTys/COM> > <代码> M>代码>,除非您有特定的原因想要<代码>数据< /代码>。大多数情况下,如果您可以使用
newtype
,您应该这样做。

您只能在构造函数上进行模式匹配,而不能在其他任何东西上进行模式匹配。您必须使用m的Monad实例来获取其中的数据。我不是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

你们两个都是!!现在我明白我做错了什么!