【问题标题】:What is the difference between pure and impure in haskell?haskell中的纯和不纯有什么区别?
【发布时间】:2013-03-03 07:10:15
【问题描述】:

haskell 中的纯和不纯有什么区别? 在haskell中做IO的时候,把纯项和不纯项分开是什么意思?

【问题讨论】:

  • 这是个把戏! Haskell 中的一切都是纯粹的——你必须离开 Haskell(比如进入运行时系统)才能得到一些不纯粹的东西。 (...但直到您在 Haskell 体验的后期,这才是一个有用的答案。)

标签: haskell functional-programming


【解决方案1】:

本质上,您希望在“不纯部分”中保留尽可能少的代码。用 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 -&gt; String。没有IO 这里。这意味着我们可以假设 addDude 至少会以这种方式运行。它将接受一个字符串并返回一个字符串。它不可能有副作用。它不可能炸毁月球。

【讨论】:

  • 不错的答案。很抱歉冒昧地修复代码中的错字。我还建议addDude 的签名如果存在于代码中,会更好地显示纯度。编写显式类型签名的一个原因就是为了记录和验证绝对不会发生的坏事。
  • @pigworker,谢谢!你知道,我想把它放在那里,但不确定这是否重要,所以我为了方便起见。
  • +1 用于对问题的雄辩讨论。然而,对于所有这些导弹来说,月球不是一个更好的地方吗?至少我们可以肯定,如果我们让他们去那里,没有人会被杀或中毒....
【解决方案2】:

纯度仅仅意味着不会产生副作用(从磁盘读取、移动机械臂等)

将纯函数与不纯函数分开意味着您可以更多地了解您的代码将要做什么。例如,当您说1 + 2 时,您可以通过它的类型 (Int -&gt; Int -&gt; Int) 确定它所做的唯一事情就是取两个数字并产生第三个数字。如果它的类型是Int -&gt; Int -&gt; IO Int,它可能会在每次将两个数字相加时移动一个机械臂。

可以在这里找到 Haskell 基础知识的良好起点: http://learnyouahaskell.com/introduction#so-whats-haskell

【讨论】:

    【解决方案3】:

    Haskell 中的一切都是纯粹的。您正在阅读的内容可能是关于 IO mondad 内部与外部的代码。一旦你将某些东西放入 IO monad,它就永远无法“逃脱”——你必须留在 IO monad。因此,IO monad 倾向于“侵入”你的代码——如果你有一个返回 IO 的东西,那么任何调用它的代码也必须返回 IO,等等。因此,最好只在必要的地方使用 IO monad,尽可能在程序的顶层,并将计算的任何部分分离为纯函数。

    【讨论】:

      猜你喜欢
      • 2014-04-19
      • 2013-07-19
      • 2011-02-10
      • 2012-03-12
      • 2020-09-02
      • 2021-06-27
      • 2019-12-14
      • 2011-06-16
      • 1970-01-01
      相关资源
      最近更新 更多