haskell - [do x] 和 [do return x] 何时评估不同?

标签 haskell monads

*Main> do 0

0


*Main> do return 0

0


*Main> do (Just 0)

Just 0


*Main> do return (Just 0)

Just 0


*Main> do Nothing

Nothing


*Main> do return Nothing

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写作

Don't read the monad tutorials.



所以,我想弄脏我的手可能会有所帮助。

我真的很感谢帮助我离开这里的人(我的意思是 doreturn ,而不是 Monad 。我知道这需要几天时间)。

最佳答案

do在单个表达式上没有任何作用:它只是一个句法先驱,表明您可以在这里使用 Action 序列(这将需要一个 monad),但是如果您不这样做,那么它与将表达式包装在层中的效果相同多余的括号。

所以你的示例 session 相当于:

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 有两种根本不同的交互式评估模式:
  • IO执行 Action ,然后结果 print 编。
  • 其他都是print按原样编辑。

  • 至关重要的是,GHCi 非常努力地将所有内容解释为 IO在继续 2 之前采取行动。所以如果你给它一个模糊的表达,比如 return 0 ,它注意到一种可能的实例化是 IO Integer .它立即默认为,执行此副作用自由 Action ,因此您在结果中看到的所有内容都是 0 .这只发生在 IO但是,不适用于任何其他 monad:
    Prelude> return 0 :: IO Integer
    0
    Prelude> return 0 :: Maybe Integer
    Just 0
    Prelude> return 0 :: [] Integer
    [0]
    

    GHCi 恰好默认为 IO当 monad 模棱两可时,但在 Haskell 中不会发生这种情况。

    关于haskell - [do x] 和 [do return x] 何时评估不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39700015/

    相关文章:

    haskell - 如何编写没有参数的 Haskell 函数?

    javascript - 是否有有效的数组 monad 转换器?

    haskell - 在 Haskell 中模拟交互的有状态对象

    exception - Haskell中的非一元错误处理?

    haskell - 将 monad 组合抽象为变压器

    haskell - 如何在 Mac OSX 上安装 haskell readline 库?

    macos - 使用部署目标构建 Haskell macOS 可执行文件

    generics - 使用标准的 haskell 泛型库进行类型化类型同构

    haskell - 单独使用的括号 () 是什么意思?

    swift - 为什么 Swift 允许双重可选?