参考透明度这个术语是什么意思?我听说它被描述为"它意味着你可以用平等替换等于",但这似乎是一个不充分的解释.
theory computer-science functional-programming referential-transparency
这些术语似乎有 不同的定义,但我总是想到一个暗示另一个; 当表达式是引用透明但不纯粹时,我无法想到任何情况,反之亦然.
维基百科为这些概念维护单独的文章并说:
从参考透明度:
如果表达式中涉及的所有函数都是纯函数,则表达式是引用透明的.此外,如果丢弃它们的值并且它们的副作用无关紧要,则表达式中可以包含一些不纯的函数.
来自纯粹的表达:
构造纯表达式需要纯函数.[...]纯表达通常被称为引用透明.
我发现这些陈述令人困惑.如果副作用所谓的"非纯函数"是微不足道的,足以让不执行他们(即替换其这种函数的调用值没有实质性改变程序),它是一样的,如果它的是纯粹的第一名,不是吗?
有没有更简单的方法来理解纯表达式和引用透明的表达式之间的差异(如果有的话)?如果存在差异,则可以理解清楚地表明它的示例表达.
language-agnostic functional-programming side-effects referential-transparency purely-functional
Haskell通常被引用为纯函数式语言的示例.鉴于存在,这怎么可能是合理的System.IO.Unsafe.unsafePerformIO?
编辑:我认为"纯功能"意味着不可能将不纯的代码引入程序的功能部分.
haskell type-systems functional-programming referential-transparency unsafe-perform-io
在功能编程方面触及Monads之后,该功能是否实际上使语言变得纯粹,或者它是否只是另一个"从监狱免费卡中获取"来推理现实世界中的计算机系统,在黑板数学之外?
编辑:
这不是有人在这篇文章中所说过的火焰诱饵,而是一个真正的问题,我希望有人可以用枪击我说,证明,这是纯粹的.
此外,我正在研究关于其他不那么纯粹的功能语言和一些使用良好设计和比较纯度的OO语言的问题.到目前为止,在我非常有限的FP世界中,我仍然没有理解Monads的纯度,你会很高兴地知道我喜欢不变性的想法,这在纯度赌注中更为重要.
monads haskell functional-programming referential-transparency
我经常听说Haskell没有变量的说法; 特别是,这个答案声称它没有,它至少被投票了九次并被接受.
那么它是否有变量,为什么?
这个问题似乎也适用于ML,F#,OCaml,Erlang,Oz,Lava和所有SSA中间语言.
variables monads haskell immutability referential-transparency
我已经使用了一些函数式编程语言,并且非常喜欢Lisps使用的s-expr语法(特别是Scheme).
我也看到了使用纯函数式语言的优势.因此:
是否有任何纯粹的功能方案(或一般的Lisps)?
scheme haskell functional-programming referential-transparency
当人们想要遍历树并保持当前位置时,Zipper数据结构很棒,但是如果他们想要跟踪多个位置,应该使用哪种数据结构?
让我用例子解释一下:
有一个简单的(幼稚?)解决方案,类似于他们在XMonad的早期版本中使用的涉及作为解释的有限的地图在这里.
也就是说,例如,在我的示例项目的情况下,我将所选节点存储在索引映射中,并用索引替换它们在主结构中的表示.但是这种解决方案有很多缺点.就像上面链接中解释的那样,或者说,在我的例子的情况下,取消选择所有节点将需要搜索整个树.
haskell functional-programming referential-transparency zipper data-structures
由于副作用破坏了参考透明度,它们是否违背功能语言的观点?
我是一个完整的新手,目前正试图通过"让你学习哈斯克尔为大好 " 来学习Haskell .我已经到达了解释如何使用命令行参数的部分,而且有些事情让我烦恼.
根据我的理解(和haskell.org的定义),动作是为了封装副作用.命令行参数是程序的给定实例的不可变输入,那么有什么意义getProgName :: IO String而不是getProgName :: String?不同之处:阻止纯函数调用的重点是getProgName什么?
更新
到目前为止,我对这个问题有了很好的答案.我接受Don Stewart是最简单和最简洁的,但Conal(及其相关的博客文章)绝对值得一读.
我需要用于模拟的小型高斯随机数列表,所以我尝试了以下方法:
import System.Random
seed = 10101
gen = mkStdGen seed
boxMuller mu sigma (r1,r2) = mu + sigma * sqrt (-2 * log r1) * cos (2 * pi * r2)
Run Code Online (Sandbox Code Playgroud)
这只是Box-Muller算法 - 给定r1,r2在[0,1]区间内的均匀随机数,它返回一个高斯随机数.
normals 0 g = []
normals n g = take n $ map (boxMuller 0 1) $ pairs $ randoms g
where pairs (x:y:zs) = (x,y):(pairs zs)
Run Code Online (Sandbox Code Playgroud)
所以我normals每次需要我的随机数列表时都会使用这个函数.
问题必须明显:它始终生成相同的序列,因为我总是使用相同的种子!我没有得到新的序列,我只是一直得到序列的前n个值.
我明确假装的是,当我输入时:
x = normal 10
y = normal 50
Run Code Online (Sandbox Code Playgroud)
我要将x作为前10个值,将map (boxMuller 0 1) $ …
random haskell functional-programming referential-transparency
haskell ×7
io ×2
monads ×2
immutability ×1
random ×1
scheme ×1
side-effects ×1
theory ×1
type-systems ×1
variables ×1
zipper ×1