我试图了解如何创建monad的规则。据我了解,这取决于我想要使用的数据类型,monad必须满足三个定律:
1. m >>= return = m
2. return x >>= f = f x
3. (m >>= f) >>= g = m >>= (\x-> f x) >>= g
好。所以对于monad Maybe
我有最后两行。对于“x
”在第三行中的含义。如果应该是一个函数,它不应该吗?
data Maybe a = Nothing | Just a
instance Monad Maybe where
(Just x) >>= f = f x
Nothing >>= _ = Nothing
_ >>= x = x
fail _ = Nothing
(我现在无法找到这个定义的来源,但我发现它在某个地方)
我发现了另一个版本 - 为什么我需要“失败”这一行呢?
data Maybe a = Nothing | Just a
instance Monad Maube where
return x = Just x
Just x >>= f = f x
Nothing >>= f = Nothing
fail _ = Nothing
答案 0 :(得分:3)
我建议您仔细阅读this chapter of 'Learn you a Haskell',它提供了一些示例,可以帮助您澄清monad是什么。
回到关于x
的问题,它不是一个函数,而是Just
中包含的值。 Maybe a
是一个包含两个不同构造函数的类型:Nothing
,表示它没有任何值,Just a
,这意味着它保存了一个类型的值a
。
让我们看一下>>=
的签名。它是(>>=) :: m a -> (a -> m b) -> m b
,这意味着它需要一个monad m a
,一个函数(a -> m b)
并返回一个monad m b
。请注意,您拥有相同的monad m
,但可能是其类型参数的不同值(从a
到b
)。
对于Maybe a
,我们需要处理两种情况:当我们有值(Just a
)或者我们没有值(Nothing
)时。实现了>>=
Maybe
,以便将f
应用于有值的值,否则只会传播Nothing
。在您的示例中,您还有_ >>= x = x
,但由于您已经详尽地匹配了所有可能的模式,因此不需要这样做。