Elixir 管道贴图正在尝试调用原始函数
以下代码用于读取文件并为每行创建Elixir 管道贴图正在尝试调用原始函数,elixir,Elixir,以下代码用于读取文件并为每行创建项记录: defmodule Ship do defrecord Item, product_code: 0, quantity: 0, destination: "" def load_data do File.read!("data") |> String.split |> Enum.map &(String.split &1, ",") |> Enum.map &am
项
记录:
defmodule Ship do
defrecord Item, product_code: 0, quantity: 0, destination: ""
def load_data do
File.read!("data")
|> String.split
|> Enum.map &(String.split &1, ",")
|> Enum.map &(list_to_item &1)
end
defp list_to_item([pc, q, d | []]) do
{parsed_q, _} = Integer.parse q
Item.new product_code: pc, quantity: parsed_q, destination: d
end
end
有一个包含以下内容的数据
文件:
1,100,London
1,30,Lisbon
3,2,Braga
问题是,当我执行load_data函数时,对Enum.map的最后一次调用似乎是试图递归调用父函数(load_data),并抛出一个BadArityError
结果如下:
iex(1)> Ship.load_data
** (BadArityError) #Function<0.127338698/1 in Ship.load_data/0> with arity 1 called with 2 arguments ({:cont, []}, #Function<30.103209896/2 in Enum.map/2>)
(elixir) lib/enum.ex:2000: Enumerable.Function.reduce/3
(elixir) lib/enum.ex:879: Enum.map/2
ship.ex:8: Ship.load_data/0
它按预期工作:
iex(2)> Ship.load_data
[Ship.Item[product_code: "1", quantity: 100, destination: "London"],
Ship.Item[product_code: "1", quantity: 30, destination: "Lisbon"],
Ship.Item[product_code: "3", quantity: 2, destination: "Braga"]]
那么,你知道第一个版本的错误来自哪里吗?难道它们不应该是等价的吗
顺便说一句,我使用的是Elixir 0.12.4。您的代码实际上相当于:
File.read!("data")
|> String.split
|> Enum.map (&(String.split &1, ",") |> Enum.map &(list_to_item &1))
您需要更多的括号,因为|>
比无括号函数应用程序具有更高的优先级:
File.read!("data")
|> String.split
|> Enum.map(&(String.split &1, ","))
|> Enum.map(&(list_to_item &1))
这是长生不老药设计中的一个不幸缺陷(也是我仍然喜欢Erlang的唯一原因)。对不起,这不是长生不老药设计中的一个不幸缺陷。一旦您注意到Elixir中的所有运算符的优先级都高于函数调用,您就会意识到具有不同优先级的
|>
实际上会导致更多的混淆。例如,我在测试中看到的断言是assert foo |>List.flatte==[1,2,3]
或类似foo=bar |>Enum.baz
的表达式,如果我们降低>
的优先级,它们的行为将不符合预期。如果我阅读assert foo |>List.flatte=[1,2,3]
我非常希望它将assert foo的结果传递给List.flatten==[1,2,3]
。也许是因为我的F#背景吧。我认为|>
-作为在线上的第一个令牌被更广泛地使用。
File.read!("data")
|> String.split
|> Enum.map(&(String.split &1, ","))
|> Enum.map(&(list_to_item &1))