4

我正在尝试学习 Haskell,但我在使用 monad 时遇到了问题。

我导入了模块Data.Maybe

但我不知道如何使用>>=运算符。

鉴于(>>=) :: Monad m => m a -> (a -> m b) -> m b我无法理解如何定义函数(a -> m b)

有人可以提供一些教学示例吗?

4

2 回答 2

14

Maybe monad 的一个相当常见的例子是除法。在某些方面,Maybe monad 表示一个计算要么给出结果 ( Just),要么失败 ( Nothing),除法就是这样:除非你除以 0,否则它是有效的,在这种情况下它是失败的。

代码总是有用的:

divide :: (Fractional a) => a -> a -> Maybe a
divide a 0 = Nothing
divide a b = Just $ a / b

使用此功能的一些示例:

> divide 1 2
Just 0.5
> divide 20 3
Just 6.666666666666667
> divide 1 0 -- Oops
Nothing

因为 Maybe 是一个 monad,我们可以使用这个divide函数进行计算并自动传播任何错误。例如以下1/x + 1安全计算

recipPlusOne :: (Fractional a) => a -> Maybe a
recipPlusOne x = divide 1 x >>= return . (+1)

-- equivalently,
recipPlusOne' x = fmap (+1) $ divide 1 x

(注意return . (+1)函数是怎样的a -> m b,因为它接受一个数字,加一个 ( (+1)),然后将它包装在 Maybe monad ( return) 中。)

错误通过传播,

> recipPlusOne 1
Just 2.0
> recipPlusOne 0.1
Just 11.0
> recipPlusOne 0 -- Oops, divide by 0
Nothing
于 2012-06-04T13:29:24.970 回答
8

对于Maybemonad 绑定函数 ( >>=) 看起来像这样:

(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b

所以,让我们定义一些Maybe a值:

> let a = Just 1
a :: Maybe Integer

:: a -> Maybe b功能:

> let f = \x -> Just (x+1)
f :: Integer -> Maybe Integer

现在我们可以使用类似中缀运算符的绑定:

> a >>= f
Just 2
it :: Maybe Integer

真正功能的另一个例子a -> Maybe b可能是:

let h :: Integer -> Maybe String; h = return . show . (+1)
h :: Integer -> Maybe String

所以h递增整数,将其转换为字符串并Maybe使用函数生成一个值return

> a >>= h
Just "2"
于 2012-06-04T13:06:00.447 回答