关于使用Maybe monad进行评估的计算查询

时间:2014-05-11 10:38:48

标签: haskell monads maybe

我目前正在学习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))

2 个答案:

答案 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不一样。