我正在尝试square
和cube
功能。
为什么square
在cube
爆炸时有效?
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
答案 0 :(得分:55)
从0.10.3开始,您需要将部分应用程序放在括号之间,并以&
运算符开头。
此版本不会有任何问题:
iex> square = &(&1 * &1)
iex> square.(5)
25
iex> cube = &(&1 * &1 * &1)
iex> cube.(5)
125
答案 1 :(得分:44)
在elixir-talk邮件列表上引用Alexei Sholik:
通常,&amp; 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
总是返回浮动。
答案 2 :(得分:2)
根据最新的Elixir documentation,有两种方法可以创建匿名函数:
# 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