我需要为特定数据类型声明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.
这可能很简单,但我无法弄明白!
答案 0 :(得分:5)
类型变量m
不是您可以模式匹配的内容,尤其不是为了区分Just
和Nothing
。考虑一下代替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