什么时候[do x]和[do return x]进行不同的评估?

时间:2016-09-26 10:08:34

标签: haskell monads

*Main> do 0
  

0

*Main> do return 0
  

0

*Main> do (Just 0)
  

只是0

*Main> do return (Just 0)
  

只是0

*Main> do Nothing
  

没有

*Main> do return Nothing
  

没有

bareDo :: a -> a
bareDo x = do x

doReturn :: Monad m => a -> m a
doReturn x = do return x

为什么do xdo return x评估相同,他们什么时候不会?

我试图理解Monad,它已经足够教程和discussion但我无法弄明白。

这甚至是post写作

  

不要阅读monad教程。

所以,我觉得弄脏手可能会有所帮助。

我非常感谢能帮到我的人(我的意思是doreturn,而不是Monad。我知道这需要几天时间。)

2 个答案:

答案 0 :(得分:19)

单个表达式上的

do完成任何事情:它只是一个语法导师,表明你可以在这里使用动作排序(这需要monad),但是如果你没有这样做,那么它与在冗余括号层中包装表达式具有相同的效果。

所以你的示例会话等同于:

Prelude> 0
0
Prelude> return 0
0
Prelude> Just 0
Just 0
Prelude> return (Just 0)
Just 0
Prelude> Nothing
Nothing
Prelude> return Nothing
Nothing

现在的问题是为什么return没有在这里完成任何事情。嗯,实际上确实如此,你只是看不到它,因为GHCi隐藏了实现细节。 GHCi有两种根本不同的交互式评估模式:

  1. IO操作已执行,然后结果print已编辑。
  2. 其他所有内容都是print
  3. 至关重要的是,在继续使用2之前,GHCi很难将所有内容解释为IO操作。因此,如果你给它一个模糊的表达式,如return 0,它会注意到一个可能的实例化是{{1 }}。它立即默认为,执行此无副作用的动作,因此您在结果中看到的只有IO Integer。这只发生在0,但不适用于任何其他monad:

    IO

    当monad处于模糊状态时,GHCi恰好默认为Prelude> return 0 :: IO Integer 0 Prelude> return 0 :: Maybe Integer Just 0 Prelude> return 0 :: [] Integer [0] ,但在Haskell中不会发生这种情况。

答案 1 :(得分:-1)

答案很好:从不,因为return :: Monad m => a -> m a接受一个对象并将其放入一个盒子中。

是的,但无法回答:当x是来自给定monad的return的固定点时。

相关问题