问题标签 [referential-transparency]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
1489 浏览

haskell - 默认情况下具有不可变变量的语言,例如 Haskell

我发现 Haskell 令人着迷的一件事是函数和变量是如何相同的。在大多数语言中,变量保存一个值,而函数执行某些操作,然后最终返回一个值。在 Haskell 中,您看不到这种差异,并且在使用 Haskell 之后,回到更“传统”的编程方式,其中变量与函数或方法不同,感觉很尴尬。如果我想得到一个值,我真的不应该担心它的来源,无论是常量值、可变变量还是复杂计算的结果!在 Haskell 中,变量只是 0 元函数

许多面向对象的语言都有一些让人感觉有点差距的属性。

任何人都可以使用类似于 Haskell 的系统指示任何其他语言吗?由于引用透明性,我认为函数式语言很常见,但我发现情况并非如此。例如,在 Lisp 中,您必须(defun)显式声明函数。

0 投票
2 回答
1525 浏览

data-structures - 是否有双向多图持久数据结构?

换句话说,我们能否有效地对持久数据结构中的多对多关系进行建模?


建议使用一对单向多图。但是,我不确定这对于在持久数据结构中的删除效果如何。假设我们有键 1..4 到值“1”..“4”,假设它们每个都引用所有其他的,所以我们有两个在两个方向上看起来都非常相似的映射:

{1 => ["2","3","4"], 2 => ["1","3","4"], ...} {"1" => [2,3, 4], "2" => [1,3,4], ...}

现在我们要从系统中完全删除项目 1。这需要在第一个映射中更改一个节点,但它需要在第二个映射中更改 n-1 个节点。对于成千上万的 n (这可能在我正在考虑的情况下),那不是相当昂贵吗?或者多图是否针对处理这种类型的更改进行了优化?这是一个病态的案例,但仍然...


四叉树似乎是一个迷人的想法。我要多考虑一下。

0 投票
3 回答
779 浏览

haskell - 如何通过隐藏“状态”更改以 sig 类型编写没有 IO 的 haskell 函数

我在 haskell 中编写了一个函数,它接受一些参数,如 Word32、String(忽略柯里化)并输出 IO Word32。现在,这是一个真正意义上的函数:对于相同的输入,输出总是相同的。没有副作用。该函数返回 IO Word32 而不是 Word32 的原因是该函数在一个循环中多次更新许多 32 位线性反馈移位寄存器 (lfsr) 和其他寄存器,以计算最终的 Word32 输出。

我的问题是:鉴于此函数实际上没有副作用,是否可以在函数实现中隐藏这些寄存器更新,以便函数返回 Word32 而不是 IO Word32?如果是这样,怎么做?

0 投票
2 回答
675 浏览

optimization - Haskell中函数调用的优化

不知道这个问题到底要谷歌什么,所以我将它直接发布到 SO:

  1. Haskell 中的变量是不可变的
  2. 纯函数应该为相同的参数产生相同的值

从这两点可以推断,如果您somePureFunc somevar1 somevar2在代码中调用两次,那么只有在第一次调用期间计算值才有意义。结果值可以存储在某种巨大的哈希表(或类似的东西)中,并在随后调用该函数时进行查找。我有两个问题:

  1. GHC真的会做这种优化吗?
  2. 如果是这样,在重复计算实际上比查找结果更便宜的情况下,行为是什么?

谢谢。

0 投票
2 回答
1112 浏览

ocaml - OCaml 中的引用透明性

我试图协调引用透明度的定义与 OCaml 如何处理多态类型和副作用。我在https://web.archive.org/web/20120729232358/http://www.csc.villanova.edu/~dmatusze/resources/ocaml/ocaml.html上读到

如果定义的含义不依赖于它所在的上下文,则称其具有引用透明性。OCaml 中的函数具有引用透明性,即更改上下文(其他变量和其他函数)不会改变您所使用的任何函数的含义已经定义了。当您调试程序时,这一事实可能至关重要,因为您可能会相当频繁地重新定义函数。

但是按照我的理解,这在 OCaml 中是不可能的,因为在返回输入函数的任何内容之前,可能会执行一大堆副作用(例如写入文件和执行其他计算)。

您可能有一个函数f : string -> string,因此f "a"不等于f "a"。我们可以将一些副作用表达式放入函数体中,这些表达式在 的类型描述中完全不可见f

例如f,可以定义为返回某个文件的第一行。在上下文中的某个地方可能有一个函数f被更改,这会影响第一行f返回的内容。或者更糟糕的是,上下文中的某些函数可能会删除f取决于哪个文件f未定义的文件。

那么 OCaml 是参照透明的还是我遗漏了什么?

0 投票
4 回答
721 浏览

data-structures - 在 Haskell 中递归修改部分数据结构

大家好,我是 Haskell 的新手,我想创建一个 Haskell 程序,可以将 DeMorgan 定律应用于逻辑表达式。问题是我不能将给定的表达式更改为新的表达式(在应用德摩根定律之后)

具体来说,这里是我的数据结构

我想创建一个接受“LogicalExpression”并在应用德摩根定律后返回“LogicalExpression”的函数。

例如,每当我在logicalExpression中找到这种模式:Neg ( Conj (Var 'a') (Var 'b') ) 时,我需要将其转换为 Conj ( Neg (Var 'a') Neg (Var 'b') )。

这个想法很简单,但是在haskell中实现起来非常困难,这就像试图创建一个搜索x并将其转换为y的函数(我们称之为Z),所以如果Z被赋予“vx”,它会将其转换为“vy " 仅在数据结构“logicalExpression”中采用字符串而不是 x 而不是 x 它采用我提到的模式并再次吐出整个logicalExpression,但模式已更改。

PS:我希望该函数采用任何复杂的逻辑表达式并使用德摩根定律对其进行简化

有什么提示吗?

提前致谢。

0 投票
3 回答
1130 浏览

data-structures - Haskell 中使用 State-Monad 的类集方法

我最近看了 Haskell 的 Monad - State。我已经能够创建与这个 Monad 一起操作的函数,但是我试图将行为封装到一个类中,基本上我试图在 Haskell 中复制这样的东西:

如果有人能提供帮助,我将不胜感激。谢谢!

0 投票
2 回答
357 浏览

python - Python 生成器 - 改变最后的结果?

我试图在我的生成器的以下两个定义之间做出决定。哪个更好?哪个“更pythonic”?有没有办法减轻每个人的缺点?

第一个修改了生成器返回的值,可能会弄乱我还没有预见到的调用代码。在这种情况下,第二个会产生 1000 个元组的垃圾,或者如果我增加“howMany”(我可能会)会产生更多。

我作为示例给出的循环只是我当前对生成器的使用。我认为我永远不会保存从中产生的值,但它是一种实用程序,可能在其他地方有用。

0 投票
6 回答
737 浏览

haskell - 如果你编译一个没有输入的程序会发生什么?(Haskell IO 纯度问题(再次))

putStrLn当使用任何参数调用时,将始终返回 type 的值IO ()。我同意这是纯粹的,我可以处理。但它是参照透明的吗?我认为是这样,因为对于任何给定的输入,您都可以将函数调用替换为IO ()将在标准输出中抛出正确字符串的函数调用。

所以我很酷putStrLn,但是getLine当不带参数调用时可以返回任意数量的东西,只要它们是 type IO String。这既不是纯粹的,也不是参照透明的,对吧?

愚蠢的迂腐问题,它可能不会改变我编写代码的方式,但我真的想一劳永逸地解决这个问题。(我知道 IO monad 会正确排序,这不是我的问题)

这对我提出了另一个问题。编译器是否足够聪明,可以识别不需要输入的程序?例如说我编译

GHC 是否足够聪明,可以将该程序简化为IO ()导致 [2,3,4,5,6,7,8,9,10,11] 被打印出来的程序?还是它仍然可以解决并在运行时评估/执行所有内容?对于不需要输入的任意程序也是如此。GHC 是否采用了整个程序是引用透明的并且可以简单地用它的值替换的事实?

0 投票
3 回答
444 浏览

haskell - 在 haskell 中使用引用透明度预先计算值

假设我们有一个这样的程序:

我希望将其编译为可执行文件仅打印 50000005000000,而无需花费太多时间和精力。

基本上,任何肯定会被计算的表达式(也许严格性分析在这里会有所帮助)都可以在编译期间预先计算(即我们使用引用透明性来表示计算值时并不重要)。

简而言之:“必须计算”+参考透明度=可以预先计算

这就像运行程序,直到我们遇到依赖于输入的东西(即程序的核心,所有输入通用的,将被预先计算)

目前是否有实现这一目标的现有机制(用 Haskell 或任何其他语言)?[请不要指向 C++ 中的模板之类的东西,因为它首先没有引用透明性。]

如果不是,这个问题有多难?[伴随的技术(和理论)问题是什么?]