从 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
。这种在不纯的上下文中使用纯函数的技术称为提升。