函数行为不一致

Ben*_*Hao 40 elixir

我正在尝试一个square和一个cube功能.为什么squarecube爆炸时工作?

square = &1 * &1
square.(5)
Run Code Online (Sandbox Code Playgroud)

工作正常

cube = &1 * &1 * &1
cube.(5)
Run Code Online (Sandbox Code Playgroud)

抛出

** (ArithmeticError) bad argument in arithmetic expression
    :erlang.*(#Function<erl_eval.6.82930912>, 5)
    erl_eval.erl:572: :erl_eval.do_apply/6
    src/elixir.erl:133: :elixir.eval_forms/3
    /private/tmp/elixir-OVih/elixir-0.8.2/lib/iex/lib/iex/server.ex:19: IEx.Server.do_loop/1
Run Code Online (Sandbox Code Playgroud)

iri*_*rio 55

0.10.3开始,您需要将部分应用程序放在括号前面的&运算符之间.

这个版本你不会遇到任何麻烦:

iex> square = &(&1 * &1)
iex> square.(5)
25
iex> cube = &(&1 * &1 * &1)
iex> cube.(5)
125
Run Code Online (Sandbox Code Playgroud)


And*_*man 44

在elixir-talk邮件列表上引用Alexei Sholik:

通常,&1仅将其所属的原始表达式作为函数.换句话说,它将AST传递给第一个父级,并用fn替换该父级.

像这样的表达式工作正常:

&1 * &1
&1 + 2
&1 * &2
Run Code Online (Sandbox Code Playgroud)

但它不能涉及更复杂的表达.

例如,当你写:

&1 * &1 * &1
Run Code Online (Sandbox Code Playgroud)

......你正在写类似于:

fn x -> fn x -> x * x end * x end
Run Code Online (Sandbox Code Playgroud)

关于elixir-core的讨论是关于&1在这些情况下需要修改的行为是否更少混淆.

但是,要回答您的具体问题,您需要更多类似的内容:

cube = fn x -> x * x * x end
Run Code Online (Sandbox Code Playgroud)

如果要使用&1,可以使用简单的表达式math.pow/2:

cube = :math.pow(&1, 3)
Run Code Online (Sandbox Code Playgroud)

...注意math.pow/2总是给出一个浮动.