gpt4 book ai didi

haskell - main 返回 IO Something 而不是 IO() 有什么用?

转载 作者:行者123 更新时间:2023-12-02 14:22:42 25 4
gpt4 key购买 nike

我正在阅读http://learnyouahaskell.com/ ...令我惊讶的是:

Because of that, main always has a type signature of main :: IO something, where something is some concrete type.

?因此 main 不必是 IO() 类型,而可以是 IO(String)IO(Int )?但这有什么用呢?

我玩了一些...

m@m-X555LJ:~$ cat wtf.hs
main :: IO Int
main = fmap (read :: String -> Int) getLine
m@m-X555LJ:~$ runhaskell wtf.hs
1
m@m-X555LJ:~$ echo $?
0
m@m-X555LJ:~$

嗯。所以我的第一个假设被证明是错误的。我认为这是 Haskell 程序将退出状态返回到 shell 的一种方式,就像 C 程序从 int main() 启动并使用 return 0 报告退出状态一样> 或返回 1

但是没有:上面的程序消耗了输入中的1,然后什么也不做,特别是似乎没有将此1返回到shell。

再进行一次测试:

m@m-X555LJ:~$ cat wtf.hs
main = getContents
m@m-X555LJ:~$ runhaskell wtf.hs
m@m-X555LJ:~$

哇。这次我尝试返回IO String。由于我不知道的原因,这次 Haskell 甚至没有等待输入,就像我返回 IO Int 时那样。该程序似乎什么也没做。

这暗示该值实际上没有在任何地方返回:显然,由于 getContents 的结果没有被使用,因此由于懒惰而跳过了整个指令。但如果是这样的话,为什么没有跳过返回 IO Int 呢?嗯,是的:我在 IO 操作上执行了 fmap read ;但同样的东西似乎也适用,只有在使用操作的结果时才需要计算 read ,这 - 正如 main = getContents 示例似乎暗示的那样 - 不是使用过,所以懒惰也应该跳过read,因此也跳过getLine,对吧?好吧,错了 - 但我很困惑为什么。

main 返回 IO Something 而不是仅返回 IO () 有什么用?

最佳答案

这实际上是多个问题,但按顺序排列:

  1. main 的“结果”没有意义,这就是为什么它可以() 或其他任何内容。根本没用过。
  2. main 中允许使用 IO () 以外的类型是为了方便;否则,您总是必须执行类似 main = void $ realMain 的操作来丢弃结果(您可能很希望有一个操作可以返回您不关心的结果)发生这种情况)这有点乏味。恕我直言,默默地丢弃东西是不好的,所以我更喜欢 main 被强制为 ::IO (),但你总是可以通过提供类型来获得这种效果自己签名,这样在实践中这并不是什么问题。
  3. 旁白:如果您想以特定的退出代码退出,请使用 System.Exit
  4. fmap read getLine 消耗输出而 getContents 不消耗输出的原因是 getContents 是惰性的,而 getLine不是 - 即 getLine 确实读取了您认为会读取的一行文本,而 getContents 仅在结果是“需要”的情况下才执行任何实际 IO haskell 世界;由于 IO 的结果不用于任何用途,这意味着如果 getContents 是您的整个 main,它不会执行任何操作。

关于haskell - main 返回 IO Something 而不是 IO() 有什么用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55771820/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com