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 單子這裡 。