2013-02-14 59 views
2

我需要声明一个单子实例的具体数据类型:模式匹配误差

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. 

这可能是很简单,但我不能图出来!

回答

5

类型变量m不是你可以模式匹配的东西,尤其不是为了区分JustNothing。想想看,代替m使用不同的可能类型会是什么意思 - 在许多情况下,这种模式匹配是完全不可能的。

要写一个实例,你需要这样的事:

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

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

要实现(>>=),您需要做类似的事情,同样使用(>>=)作为Monad实例m

顺便提一下,除非您有特定的原因需要data,否则您应该考虑使用newtype作为M。大多数时候,如果你可以使用newtype,你应该。

0

您只能对构造函数进行模式匹配,而不能对其他任何模式进行匹配。您必须使用m的Monad实例才能找到里面的Maybe数据。我不是100%肯定这有你想要的行为,但它确实是typecheck。

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 
+0

Thnaks你们俩!现在我明白我做错了什么! – nicoan 2013-02-14 20:35:29