haskell中纯和不纯有什么区别?在haskell中做IO的时候,把纯项和不纯项分开是什么意思?
3 回答
本质上,您希望在“不纯部分”中保留尽可能少的代码。用 IO monad 编写的代码永远充满不安全感。带有签名的函数IO Int
将在 IO monad 中返回一个整数,但除此之外它还可以向月球发送核导弹。如果不研究每一行代码,我们就无法知道。
例如,假设您要编写一个程序,该程序接受一个字符串并在其上附加“, dude”。
main = do
line <- getLine
putStrLn $ line ++ ", dude"
代码的某些部分需要在 IO monad 中,因为它们有副作用。这包括 getLine 和 putStrLn。但是,将两个字符串放在一起不会。
main = do
line <- getLine
putStrLn $ addDude line
addDude input = input ++ ", dude"
addDude 的签名表明它是纯的:String -> String
。这里没有IO
。这意味着我们可以假设 addDude 至少会以这种方式运行。它将接受一个字符串并返回一个字符串。它不可能有副作用。它不可能炸毁月球。
纯度仅仅意味着不会产生副作用(从磁盘读取、移动机械臂等)
将纯函数与不纯函数分开意味着您可以更多地了解您的代码将要做什么。例如,当您说 时1 + 2
,您可以通过它的类型 ( Int -> Int -> Int
) 确定它所做的唯一事情就是取两个数字并产生第三个数字。如果它的类型是Int -> Int -> IO Int
,它可能会在每次将两个数字相加时移动一个机械臂。
可以在这里找到 Haskell 基础知识的良好起点:http: //learnyouahaskell.com/introduction#so-whats-haskell
Haskell 中的一切都是纯粹的。您正在阅读的内容可能是关于 IO mondad 内部与外部的代码。一旦你将某些东西放入 IO monad,它就永远无法“逃脱”——你必须留在 IO monad。因此,IO monad 倾向于“侵入”你的代码——如果你有一个返回 IO 的东西,那么任何调用它的代码也必须返回 IO,等等。因此最好只在必要的地方使用 IO monad,尽可能在程序的顶层,并将计算的任何部分分离为纯函数。