【发布时间】:2017-01-17 01:45:25
【问题描述】:
我注意到 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]
但这并没有,因为它考虑了宏的 do 块的第二行部分的 |> Mod.func:
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]
【问题讨论】:
标签: elixir