IO monad
没有办法从 IO a 类型的表达式中获取 a 类型的值,并且不应该存在。这实际上是 monad 用于模拟 IO 的很大一部分原因。
IO a 类型的表达式可以被认为是表示可以与现实世界交互的动作,并且如果被执行,将导致 a 类型的某些东西。例如,前奏中的函数 getLine::IO String 并不意味着在 getLine 下面有一些我可以提取的特定字符串 - 这意味着 getLine 表示从标准输入获取一行的动作。
毫不奇怪,main::IO (),因为 Haskell 程序确实代表了与现实世界交互的计算/动作。
你可以对 IO a 类型的表达式做些什么,因为 IO 是一个 monad:
-
使用
(>>)对两个动作进行排序,以生成执行第一个动作的新动作,丢弃它产生的任何值,然后执行第二个动作。-- print the lines "Hello" then "World" to stdout putStrLn "Hello" >> putStrLn "World" -
有时你不想丢弃在第一个动作中产生的值 - 你真的希望它被送入第二个动作。为此,我们有了
>>=。对于IO,它的类型为(>>=) :: IO a -> (a -> IO b) -> IO b。-- get a line from stdin and print it back out getLine >>= putStrLn -
取一个正常值并将其转换为一个动作,它立即返回你给它的值。在你开始使用
do表示法之前,此功能不太明显有用。-- make an action that just returns 5 return 5
更多来自 Haskell 的维基上的 IO 单子这里 。