假设此代码:
g :: Maybe Int
g = do
x <- Just 5 -- THIS LINE, `x` is plain Int
Just x
是:
的别名g = Just 5 >>= \x -> Just x
我的问题是,作业x <- Just 5
导致x
类型为Int
而非Maybe Int
这一事实并不令人困惑吗?或者我错了吗?
答案 0 :(得分:3)
不,它不会令人困惑。此外,如果您将示例扩展到更接近现实世界的问题,您甚至会看到这一切的原因。 E.g:
g :: Maybe Int
g = do
x <- Just 5 -- THIS LINE, `x` is plain Int
Just (x + 3)
如果x
仍然是Maybe Int
?
我认为this tutorial可能会帮助你理解monad。
答案 1 :(得分:2)
如果您认为x :: Int
令人困惑,那就错了。这里真正的困惑是您将x <- Just 5
视为赋值。为了分配任何东西,首先需要能够提取值。对于某些monad而言,这是可能的,但不是所有的monad。例如,Maybe a
只存储一个值,因此您可以想象x <- Just 5
从Maybe Int
“提取”一个值;但是,一旦你考虑一个列表,这个类比就会失败:[a]
,其中x <- [1..5]
不再与作业直接对应。这也是为什么没有从任意monad中提取值的函数的原因 - 你如何从Int
“提取”[Int]
?你如何从Int
“提取”Cont a Int
?
您需要通过几个示例来了解成为仿函数或monad的含义。最好将m Int
视为“具有Int的容器”,而是将“m
视为”Int
- 其中包含“。也就是说,某些m
具有特定于m
的行为,以及特定于Int
的行为。 monadic操作必须遵守特定的法律,因此您可以不断修改“m
一些Int
- 其中”例如“m
Char
<=<
它的内涵“。
我认为最好考虑>>=
,这是一个“有趣的作品”,而不是<-
或{{1}},这可能被误认为是“提取价值”。