我目前正在学习monad计算的基础知识。我一直在研究代码片段,我相信我知道他们做了什么,但我可能需要一些澄清。它涉及一个Maybe monad的实例。
有一些函数试图计算尾部和一个试图计算列表头部的函数。使用列表[1,2,3,4,5] = Just 3
函数func3
似乎在func2
上“跳过”额外的计算步骤。我是否正确地说func3
获取计算结果并将其提供给下面的尾部计算,然后计算其尾部,然后将该计算的结果传递给计算头部的函数?
如果是这样,为什么我们需要让func2
忽略初始计算的结果?在我看来好像它运行myTail xs
计算,然后将其值传递给函数,该函数使用初始列表而不是尾部计算的结果。
因此,这只是说明每个a, b, c
的冗余步骤吗?我假设func3
也相当于func1
,只有最高的计算是a
。
非常感谢所有人。
--computes head
myHead :: [a] -> Maybe a
myHead [] = Nothing
myHead (x:xs) = Just x
--computes tail
myTail :: [a] -> Maybe [a]
myTail [] = Nothing
myTail (x:xs) = Just xs
--below are all equivalent
func1 :: [a] -> Maybe a
func1 xs =
do a <- myTail xs
b <- myTail a
c <- myHead b
return c
func2 :: [a] -> Maybe a
func2 xs =
myTail xs >>=
(\a -> myTail xs >>=
(\b -> myTail b >>=
(\c -> myHead c)))
func3 :: [a] -> Maybe a
func3 xs =
myTail xs >>=
(\a -> myTail a >>=
(\b -> myHead b))
答案 0 :(得分:2)
在规范monad操作中等效于func1的 do 表示法,将变量移动到以下lambda的参数位置
func4 :: [a] -> Maybe a
func4 xs =
myTail xs >>= \a ->
myTail a >>= \b ->
myHead b >>= \c ->
return c
实际上最后一个lambda不会改变前一行结果,因此可以将其抑制为导致func3。
答案 1 :(得分:1)
是的,你是对的。 3个函数func1,func2,func3做同样的事情。 func2有一个额外的步骤,这是不必要的。 func1使用do符号表示与func3完全相同的计算。但是func1和func2的a,b和c不一样。