为什么"Main.main","IO()"的类型而不是"IO a"?

The*_*nce 2 haskell

为什么类型Main.main必须是IO ()IO StringIO IntIO whatever

main :: IO ([] Char) -- Type error
main = (>>) ((>>=) getLine putStrLn) getLine
Run Code Online (Sandbox Code Playgroud)

J. *_*son 5

如果你读IO a为"的IO产生的计算a",那么它引出了一个问题,以与运行时所做的a那个main生产.它可以放弃它.这需要像这样的功能

void :: IO a -> IO ()   -- defined more generally in Control.Monad
Run Code Online (Sandbox Code Playgroud)

然后给我们

realMain :: IO ()
realMain = void main
Run Code Online (Sandbox Code Playgroud)

除了文档之外,这没有特别的问题.如果我问你的价值,IO a那么我可能会选择做些什么仍然存在一些不确定性a.如果我要求一个值IO ()那么不确定性会减少:我可以随时创造()自己的价值,我不需要你的价值,因此我只关心运行IO计算的副作用.

这样可以更好地匹配实际使用情况,main以便Haskell运行时可能要求更高的类型清晰度main :: IO ().

这也迫使创作者main明确他们所做的任何"返回值".如果我有一个,mainish :: IO a那么我需要void在将它交给运行时之前明确它.


所有人都说,正如Sibi指出的那样,GHC实际上接受main :: IO a并默默地丢弃了a,所以这一点有点没有实际意义.请参阅Haskell报告第5章的介绍.