is_integer()不能与Enum.all一起使用?

时间:2016-08-09 12:33:57

标签: elixir

这里的Elixir noob总数。这是我的问题:

使用Enum.all?/2函数时,我们将函数作为第二个参数传递:

iex(19)> is_int = &(is_integer(&1))
iex(20)> Enum.all?(list, is_int)
true

那么,为什么我不能直接通过is_integer

iex(21)> Enum.all?(list, is_integer)
** (CompileError) iex:21: undefined function is_integer/0
    (stdlib) lists.erl:1354: :lists.mapfoldl/3
    (stdlib) lists.erl:1355: :lists.mapfoldl/3

is_integer不是函数吗?从错误看起来就是这样。我们在那里看到的mapfoldl是什么?

4 个答案:

答案 0 :(得分:4)

您必须捕获此功能。使用:

Enum.all?(list, &(is_integer(&1))

答案 1 :(得分:4)

Elixir就是所谓的Lisp-2语言 - 常规函数(通常称为命名函数)和捕获为值的函数(通常称为匿名函数)占用不同的空间,被不同地调用并使用不同的运算符。

使用defdefp创建一个命名函数,并使用括号调用命名函数 - 例如foo()

使用&运算符将命名函数转换为匿名函数 - 例如x = &foo/1

您使用fn创建一个匿名函数,并在括号前面调用. - 例如foo.()

匿名函数是所有其他值 - 整数,映射等,因此您可以将它们作为所有其他值传递。命名函数只能被调用或转换为匿名函数,它们不能直接传递。

答案 2 :(得分:2)

将匿名函数绑定到现有函数时,这3个是相等的:

is_int = fn n -> is_integer(n) end
is_int = &is_integer(&1)
is_int = &is_integer/1

最后一个是最简洁的,因为它只需要函数名称和arity。

注意,因为启动IEx时会自动导入内核模块中的函数,所以上面的匹配是行为

is_int = &Kernel.is_integer/1

在这种情况下,使用捕获运算符&捕获命名函数后,可以将其传递给任何期望函数作为参数的函数。或者直接传递捕获的函数。

Enum.all?(list, is_int)
Enum.all?(list, &is_integer/1) 

答案 3 :(得分:0)

您可以直接使用is_integer功能

Enum.all?(list, fn(i) -> is_integer(i) end)

这也有效

Enum.all?(list, &(is_integer(&1)))