假设这段代码:
g :: Maybe Int
g = do
x <- Just 5 -- THIS LINE, `x` is plain Int
Just x
是以下的别名:
g = Just 5 >>= \x -> Just x
我的问题是,分配导致type和 notx <- Just 5
的事实是否令人困惑?还是我错了?x
Int
Maybe Int
不,这并不令人困惑。此外,如果您将示例扩展为更接近现实世界的问题,您甚至会看到所有这一切的原因。例如:
g :: Maybe Int
g = do
x <- Just 5 -- THIS LINE, `x` is plain Int
Just (x + 3)
x
如果仍然是 a ,你将如何解决这个问题Maybe Int
?
我认为本教程可能对您理解 monad 有很大帮助。
如果您认为x :: Int
令人困惑,那您就错了。这里真正的困惑是您将x <- Just 5
其视为任务。为了分配任何东西,您首先需要能够提取值。这对于某些单子是可能的,但不是所有单子。例如,Maybe a
其中只存储一个值,因此您可以想象从;中x <- Just 5
“提取”一个值。Maybe Int
但是一旦你考虑一个列表,这个类比就失败了:[a]
,其中x <- [1..5]
不再与分配有直接对应关系。这也是为什么没有从任意 monad 中提取值的函数的原因——你如何Int
从 a 中“提取” a [Int]
?你如何Int
从 a 中“提取” a Cont a Int
?
您需要通过几个示例来理解作为函子或 monad 的含义。最好m Int
不要将其视为“具有 Int 的容器”,而应将其视为“其中包含m
一些Int
-ness”。这就是说它是一些m
具有特定于的m
行为,以及特定于 的行为Int
。monadic 操作必须遵守特定的规律,因此您可以一致地将“ m
with some Int
-ness in it”修改为,例如,“ m
with some Char
-ness in it”。
我认为最好考虑<=<
,这是一个“有趣的组合”,而不是>>=
or <-
,它可能被误认为是“提取值”。