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 单子这里 。