41

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

square = &1 * &1
square.(5)

工作正常,而

cube = &1 * &1 * &1
cube.(5)

投掷

** (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
4

3 回答 3

55

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

这个版本你不会有任何问题:

iex> square = &(&1 * &1)
iex> square.(5)
25
iex> cube = &(&1 * &1 * &1)
iex> cube.(5)
125
于 2013-11-01T00:31:49.663 回答
44

在 elixir-talk 邮件列表中引用 Alexei Sholik 的话:

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

像这样的表达式工作得很好:

&1 * &1
&1 + 2
&1 * &2

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

例如,当你写:

&1 * &1 * &1

...您正在编写类似于:

fn x -> fn x -> x * x end * x end

关于 elixir-core 的讨论是关于&1在这些情况下是否需要修改的行为以减少混乱。

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

cube = fn x -> x * x * x end

如果你想使用&1,你可以使用一个简单的表达式math.pow/2

cube = :math.pow(&1, 3)

...请注意,math.pow/2总是会返回一个浮点数。

于 2013-06-08T17:59:03.613 回答
2

根据最新的 Elixir文档,有两种创建匿名函数的方法:

# first one, more explicit
cube = fn x -> x * x * x end

#second one, syntactic sugar applied
cube = &(&1*&1*&1)

#calling them is the same
IO.puts cube.(8) # should be 512
于 2016-05-30T06:55:02.197 回答