Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Erlang:do列表理解筛选器短路_Erlang - Fatal编程技术网

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
,其中包含匹配on
true
的子句,另一个
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