Elixir:通过管道传递给函数的错误是内联理解的结果 [英] Elixir: error when piping to a function the result of inline comprehension
问题描述
当使用Elixir的 for
理解将结果通过管道传递到函数中时,我发现了一些令人惊讶的事情。
例如,这些形式有效:
foo = fn(list)->
for n<-list do
n + 1
end
|> Enum.reverse
end
foo。[[1,2,3])
#[4,3,2]
foo = fn (清单)->
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)协议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:枚举。 -reduce / 3-lists ^ foldl / 2-0- / 3
我想这与宏的扩展方式和返回值有关,但是有趣的是,这些工作:
bar = fn(list)->
如果为true,请执行:列出
|> Enum.reverse
end
bar([1,2,3])
#[3,2,1]
bar = fn (清单)->
如果为true,请执行:Enum.map(list,&(& 1 + 1))
|> Enum.reverse
end
bar。([1,2,3])
#[4,3,2]
我认为是因为:
<警告:您正在使用不带括号的函数调用
,这可能是不明确的。请用括号将要传递给函数的函数包装到
中。
这有效:
iex()> foo = fn(list)->
...()> (对于n<-list,执行: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 |>倒数
结束
和 n +1
不是列表
,因此(Protocol.UndefinedError)协议Enumerable未针对2
I've noticed something surprising with Elixir's for
comprehensions when used to pipe the results into a function.
For example, these forms work:
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]
But this doesn't, as it considers the |> Mod.func
on the second line part of the do
block of the macro:
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
I would guess that is has to do with how macros are expanded and their value returned, but interestingly these work:
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]
I think it's because of:
warning: you are piping into a function call without parentheses, which may be ambiguous. Please wrap the function you are piping into in parentheses.
This works:
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]
without parentheses your function like:
foo = fn(list) ->
for n <- list, do: n + 1 |> Enum.reverse
end
and n + 1
isn't a list
so (Protocol.UndefinedError) protocol Enumerable not implemented for 2
这篇关于Elixir:通过管道传递给函数的错误是内联理解的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!