我试图调整引用透明度的定义与OCaml如何处理多态类型和副作用.我在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是透明的透明还是我错过了什么?
大家好,我是Haskell的新手,我想创建一个可以应用DeMorgan关于逻辑表达式的法则的Haskell程序.问题是我无法将给定表达式更改为新表达式(在应用DeMorgan定律后)
具体来说,这是我的数据结构
data LogicalExpression = Var Char
| Neg LogicalExpression
| Conj LogicalExpression LogicalExpression
| Disj LogicalExpression LogicalExpression
| Impli LogicalExpression LogicalExpression
deriving(Show)
Run Code Online (Sandbox Code Playgroud)
我想创建一个函数,它接受"LogicalExpression"并在应用DeMorgan定律后返回"LogicalExpression".
例如,每当我在logicalExpression中找到这种模式:Neg(Conj(Var'a')(Var'b'))时,我需要将其转换为Conj(Neg(Var'a')Neg(Var'b') ).
这个想法很简单,但是在haskell中很难实现,就像试图创建一个函数(让我们称之为Z)来搜索x并将其转换为y,所以如果Z给出"vx"它将它转换为"vy" "只代替在数据结构中使用的字符串"logicalExpression"而不是x它采用我提到的模式并再次吐出整个logicalExpression,但模式已更改.
PS:我希望函数采用任何复杂的逻辑表达式,并使用DeMorgan定律简化它
任何提示?
提前致谢.
我正在学习Haskell.如果我理解正确,Haskell中的一个简单函数总是在引用透明.我认为这意味着它的输出仅取决于传递给它的参数.
但是函数f可以调用g外部作用域中定义的另一个函数.所以从这个意义上讲,f回归价值取决于其定义g.并且函数g不f作为参数传递- 至少不是显式的.这不会破坏参考透明度吗?
我们注意到java 8使用了参考透明度 :
我测试了很多代码来检测这个RT,例如:
public class ReferentialTransparency {
public static int triple(int number) {
System.out.println(number);
try {
Thread.sleep(500);
} catch (Exception e) {
}
return number* 3;
}
public static void main(String[] args) {
List<Integer> vals=Arrays.asList(1,2,3,4,3);
System.out.println(vals.parallelStream()
.mapToInt(ReferentialTransparency::triple)
.sum());
}
}
Run Code Online (Sandbox Code Playgroud)
安慰 :
3
4
2
1
3
39
Run Code Online (Sandbox Code Playgroud)
我注意到Java 8运行三重方法,即使有一个元素出现了两次3.
正如Istvan解释的那样,我的问题是:
如果三重引用透明,为什么编译器不会优化重复调用三元组(3)?
我们知道纯函数:
这导致我们引用透明性-表达式可以替换为值而不改变程序的行为。
这就告诉我们,一个程序可以说是纯粹的功能,如果它不包括在该程序的运行环境中的实体的破坏性修改(更新)。
当我们查看软件事务内存时,我们会看到类似于数据库事务的并发控制机制,用于控制并发计算中对共享内存的访问。但它本身并没有什么特别的功能。
我的问题是:我们可以考虑 Clojure 的 STM“功能性”吗?
functional-programming clojure referential-transparency purely-functional stm
对不起,这里有一个新问题,但Haskell如何知道不会将引用透明度应用于例如readLn或putStrLn两次相同的字符串?是因为IO参与了吗?IOW,编译器不会将引用透明度应用于返回的函数IO吗?
I have this code
data Slist a = Empty | Scons (Sexp a) (Slist a)
data Sexp a = AnAtom a | AnSlist (Slist a)
data Fruit = Peach | Apple | Pear | Lemon | Fig deriving (Show,Eq)
sxOccurs oatm sxp =
let slOC Empty = 0
slOC (Scons se sls) = (seOC se) + (slOC sls)
seOC (AnAtom atm) = if (atm == oatm) then 1 else 0
seOC (AnSlist sla) = slOC sla
in seOC sxp
Run Code Online (Sandbox Code Playgroud)
As …
我对 F# 不是很了解,但我喜欢函数式编程,因此我使用 F# 作为我的一些个人项目的灵感。
最近在读一篇关于F#新特性的文档,很喜欢其中操作符的一部分nameof。
然而,在深入研究这个想法之后,我意识到它可能不是引用透明的......就像这样,表达式可以被它的值替换,反之亦然,而且它就可以工作。
所以...
let sum = +;
nameof (sum)
Run Code Online (Sandbox Code Playgroud)
应该返回相同的
nameof (+)
Run Code Online (Sandbox Code Playgroud)
但他们不...
那么……缺乏引用透明度是故意的吗?函数式程序员如何将其与函数式编程的原则相协调?
在写这个问题时,我意识到它的nameof行为就像一个宏,因此,同样的问题也适用于宏。
FP 程序员如何协调宏的非引用透明度与 FP 原则?
macros f# functional-programming scala referential-transparency
我最近看过Haskell的Monad - State.我已经能够创建与Monad一起运行的函数,但我正在尝试将行为封装到类中,基本上我正在尝试在Haskell中复制这样的事情:
class A {
public:
int x;
void setX(int newX) {
x = newX;
}
void getX() {
return x;
}
}
Run Code Online (Sandbox Code Playgroud)
如果有人能帮助我,我将非常感激.谢谢!
haskell translate referential-transparency state-monad data-structures