Elixir:管道到函数时出现内联理解结果时出错

时间:2016-09-09 01:40:42

标签: elixir

当用于将结果传递给函数时,我注意到Elixir的for理解令人惊讶的事情。

例如,这些表格有效:

foo = fn(list) ->
  for n <- list do
    n + 1
  end
  |> Enum.reverse
end

foo.([1,2,3])
# [4, 3, 2]

foo = fn(list) ->
  for(n <- list, do: (n + 1))
  |> Enum.reverse
end

foo.([1,2,3])
# [4, 3, 2]

但是这不是,因为它考虑了宏的|> Mod.func块的第二行部分的do

foo = fn(list) ->
  for n <- list, do: n + 1
  |> Enum.reverse
end

foo.([1,2,3])
** (Protocol.UndefinedError) protocol Enumerable not implemented for 2
    (elixir) lib/enum.ex:1: Enumerable.impl_for!/1
    (elixir) lib/enum.ex:116: Enumerable.reduce/3
    (elixir) lib/enum.ex:1636: Enum.reduce/3
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
    (stdlib) erl_eval.erl:228: :erl_eval.expr/5
    (elixir) lib/enum.ex:1623: Enum."-reduce/3-lists^foldl/2-0-"/3

我猜这与宏如何扩展并返回它们的值有关,但有趣的是这些工作:

bar = fn(list) ->
  if true, do: list
  |> Enum.reverse
end
bar.([1,2,3])
# [3, 2, 1]


bar = fn(list) ->
  if true, do: Enum.map(list, &(&1 + 1))
  |> Enum.reverse
end
bar.([1,2,3])
# [4, 3, 2]

1 个答案:

答案 0 :(得分:3)

我认为这是因为:

  

警告:你在没有括号的情况下进入函数调用,   这可能是模棱两可的。请包装您输入的功能   在括号中。

这有效:

iex()> foo = fn(list) ->
...()> (for n <- list, do: n + 1)
...()> |> Enum.reverse
...()> end
#Function<6.52032458/1 in :erl_eval.expr/5>
iex()> foo.([1,2,3])
[4, 3, 2]

没有括号你的功能如下:

foo = fn(list) ->
  for n <- list, do: n + 1 |> Enum.reverse
end

n + 1不是list所以(Protocol.UndefinedError) protocol Enumerable not implemented for 2