【问题标题】:Inconsistent Functions behavior不一致的函数行为
【发布时间】:2023-03-11 20:43:01
【问题描述】:

我正在尝试 squarecube 函数。 为什么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

【问题讨论】:

  • 从这篇文章中删除了Erlang 标签。这对 Elixir 的人来说更重要。

标签: elixir


【解决方案1】:

由于0.10.3,您需要将部分应用程序放在括号之间,前面是&amp; 运算符。

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

iex> square = &(&1 * &1)
iex> square.(5)
25
iex> cube = &(&1 * &1 * &1)
iex> cube.(5)
125

【讨论】:

【解决方案2】:

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

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

像这样的表达就可以了:

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

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

例如,当你写:

&amp;1 * &amp;1 * &amp;1

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

fn x -&gt; fn x -&gt; x * x end * x end

在 elixir-core 上有讨论是否需要修改 &amp;1 的行为以减少在这些情况下的混淆。

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

cube = fn x -&gt; x * x * x end

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

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

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

【讨论】:

  • 越用elixir,越觉得开发者不知道怎么写解析器。
【解决方案3】:

根据最新的 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

【讨论】:

    猜你喜欢
    • 2018-12-26
    • 1970-01-01
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    相关资源
    最近更新 更多