從 IO 中獲取一個

一個常見的問題是“我有一個 IO a 的值,但我想對 a 值做一些事情:我如何獲得它?” 如何對來自外部世界的資料進行操作(例如,遞增使用者鍵入的數字)?

關鍵是如果你對不純粹獲得的資料使用純函式,那麼結果仍然不純。這取決於使用者做了什麼! IO a 型別的值代表“產生型別 a 的值的副作用計算”,它只能通過(a)將其組合成 main 和(b)編譯和執行程式來執行。出於這個原因,在純粹的 Haskell 世界中沒有辦法“將 a 取出”。

相反,我們想要構建一個新的計算,一個新的 IO 值,它在執行時使用 a 值。這是組成 IO 值的另一種方式,所以我們再次使用 do-notation:

-- assuming
myComputation::IO Int

getMessage::Int -> String
getMessage int = "My computation resulted in: " ++ show int
 
newComputation::IO ()
newComputation = do
  int <- myComputation       -- we "bind" the result of myComputation to a name, 'int'
  putStrLn $ getMessage int   -- 'int' holds a value of type Int

在這裡,我們使用純函式(getMessage)將 Int 轉換為 String,但我們正在使用 do 表示法將其應用於計算執行 (之後)的計算結果。結果是更大的 IO 計算,newComputation。這種在不純的上下文中使用純函式的技術稱為提升