Erlang:do列表理解筛选器短路
假设我有:Erlang:do列表理解筛选器短路,erlang,Erlang,假设我有: [ X || X<- L, some_expensive_boolean(X), some_expensive_boolean2(X)] [X | | X基于以下原因短路: -module(shortcircuit). -export([test/0]). test() -> L = [1, 2, 3], [ X || X <- L, some_expensive_boolean(X), some_expensive_boolean2(X)]. s
[ X || X<- L, some_expensive_boolean(X), some_expensive_boolean2(X)]
[X | | X基于以下原因短路:
-module(shortcircuit).
-export([test/0]).
test() ->
L = [1, 2, 3],
[ X || X <- L, some_expensive_boolean(X), some_expensive_boolean2(X)].
some_expensive_boolean(X) ->
io:format("In some_expensive_boolean: ~p~n", [X]),
false.
some_expensive_boolean2(X) ->
io:format("In some_expensive_boolean2: ~p~n", [X]),
true.
让我们创建一个示例:
$ cat test.erl
-module(test).
-export([show/0]).
show() ->
[ X || X <- [1,2,3,4,5], bigger(X), smaller(X)].
bigger(X) ->
io:format("bigger ~p~n", [X]),
X > 2.
smaller(X) ->
io:format("smaller ~p~n", [X]),
X < 4.
所以答案是:没有。答案是没有。它短路了
1> [ X || X <-[1,2], begin io:format("Test 1: ~p~n", [X]), X rem 2 =:= 0 end, io:format("Test 2: ~p~n", [X]) =:= ok ].
Test 1: 1
Test 1: 2
Test 2: 2
[2]
1>[X | | XTL;DR:No,一些昂贵的布尔2/1
没有被调用
有几种方法可以验证这一点
1.让函数在调用时打印某些内容。
2.检查生成的核心Erlang代码。
使用+to_core
选项编译模块将生成带有代码的lc.core
文件,该文件看起来有点像Erlang,但有自己的语法,但语义非常相似
erlc +to_core lc.erl
生成的代码非常详细,因此我不会将其粘贴到这里,但要点是有两个嵌套的case
表达式,一个调用f/1
,其中包含匹配ontrue
的子句,另一个case
调用g/1
1> [ X || X <-[1,2], begin io:format("Test 1: ~p~n", [X]), X rem 2 =:= 0 end, io:format("Test 2: ~p~n", [X]) =:= ok ].
Test 1: 1
Test 1: 2
Test 2: 2
[2]
-module(lc).
-export([lc/1]).
lc(L) ->
[X || X <- L, f(X), g(X)].
f(X = 2) ->
erlang:display({f, 2}),
false;
f(X) ->
erlang:display({f, X}),
true.
g(X) ->
erlang:display({g, X}),
true.
1> lc:lc(lists:seq(1, 4)).
{f,1}
{g,1}
{f,2} %% g is not called here
{f,3}
{g,3}
{f,4}
{g,4}
[1,3,4]
erlc +to_core lc.erl