10

=:=将 Erlang 中的函数与运算符, ==, <, >, =<,进行比较是什么意思>=

我正在和解释器一起玩,得到了这些结果:

Eshell V5.9.2  (abort with ^G)
1> X = fun() -> {} end.
#Fun<erl_eval.20.82930912>
2> Y = fun() -> {} end.
#Fun<erl_eval.20.82930912>
3> 
3> {X == X, X =:= X}.
{true,true}
4> {X >= X, X =< X}.
{true,true}
5> {X > X, X < X}.
{false,false}
6> 
6> {X == Y, X =:= Y}.
{true,true}
7> {X >= Y, X =< Y}.
{true,true}
8> {X > Y, X < Y}.
{false,false}

这是有道理的。它看起来像是在比较两个函数的抽象语法树。

但是在本次会议中XY再次定义相同但不同,现在也一样X<Y吗?

Eshell V5.9.2  (abort with ^G)
1> X = fun() -> {} end.
#Fun<erl_eval.20.82930912>
2> 
2> {X == X, X =:= X}.
{true,true}
3> {X >= X, X =< X}.
{true,true}
4> {X > X, X < X}.
{false,false}
5> 
5> Y = fun() -> {} end.
#Fun<erl_eval.20.82930912>
6> 
6> {X == Y, X =:= Y}.
{false,false}
7> {X >= Y, X =< Y}.
{false,true}
8> {X > Y, X < Y}.
{false,true}

所以看起来它没有比较 AST任何类型的唯一引用。也许它正在比较参考,只是一些优化正在发生并X绑定Y到相同的参考?如果对此有一些解释,不同的虚拟机或不同的节点会发生什么?

4

2 回答 2

4

shell中2次求值的区别来自于空行6>。如果您使用函数 erlang:fun_info/1 查看乐趣,您会看到在这种情况下,子句以不同的数字存储(即 2 而不是 1)。

如果你再次输入 Y 的定义(没有空行)你会得到一个不匹配的结果,如果你之前输入一个空行,就可以了。

我认为这是使用 shell 的副作用,但行为在程序中是一致的。当然 > 或 < 的含义并不明显,但 == 是的。还有一件好事是定义了 Erlang 术语的顺序,因此可以对具有可预测行为的任何术语列表进行排序:

number < atom < reference < fun < port < pid < tuple < list < bit string
于 2012-10-26T08:57:48.680 回答
1

这种行为在 shell 和编译模块中是不同的。至于模块==中的and=:=运算符,我很确定这些运算符返回iff:true

  • 这两个函数都在代码中的相同位置定义(在 shell 中不是这样!)
  • 根据各自的 ( ==/ =:=) 运算符,它们的有效闭包相等。

例如用代码

test(A, B) ->
  fun(C) -> {A, C} end.

应满足以下条件:

> test(1, x) == test(1, y).
true.
> test(1, x) =:= test(1, y).
true.
> test(1, x) == test(1.0, y).
true.
> test(1, x) =:= test(1.0, y).
false.

注意B属于内部函数的闭包因此不影响比较结果。

于 2020-11-23T11:55:21.953 回答