【问题标题】:What is the correct syntax for this Elixir expression?这个 Elixir 表达式的正确语法是什么?
【发布时间】:2017-04-23 22:57:37
【问题描述】:

这个代码sn-p给我了,作者没有测试过,

|> (fn l ->[?[, Enum.map(l, &([inspect(limit: :infinity), ?\n])), ?]] end).()

作为流水线命令序列的一部分,该命令使用DataMorph 库将数据从 CSV 文件转换为struct,并将结果作为常规 Elixir 列表输出以输入到 Elixir 源 - 即添加周围的括号, 并用逗号分隔列表中的元素。

这就是序列的样子:

File.stream!('tmp.csv') \
|> DataMorph.structs_from_csv("open-register", :iso_country) \
|> (fn l ->[?[, Enum.map(l, &([inspect(limit: :infinity), ?\n])), ?]] end).()
|> (&File.write('output.txt',&1)).()

这是在iex运行时的错误信息:

* (CompileError) iex:55: invalid args for &, expected an expression in the format of &Mod.fun/arity, &local/arity or a capture containing at least one argument as &1, got: [inspect(limit: :infinity), 10]
    (elixir) expanding macro: Kernel.|>/2
             iex:55: (file)

sn-p的故障在哪里?

【问题讨论】:

  • 这行得通吗? |> (fn l ->[?[, Enum.map(l, &([inspect(&1, limit: :infinity), ?\n])), ?]] end).()
  • @Dogbert 它编译正确并添加了左括号和右括号,但不包括分隔逗号。这是棘手的部分,因为必须进行测试以确保它不是附加之前的最后一项。
  • 没有代码可以用逗号分隔项目。 |> (fn l ->[?[, Enum.map(l, &([inspect(&1, limit: :infinity), ?\n])) |> Enum.intersperse(?,), ?]] end).() 怎么样?你能发布数据和预期的输出吗?
  • 您的建议部分有效,但逗号被附加到后续条目中,而不是被附加并导致语法错误。即,%StructType.TplParams{xxx,而不是将逗号附加到上一行,下一行从%StructType.TplParams{xxx 开始。 pastebin.com/DCrpNDUh 我认为正确的方法是在inspect 公式中使用,,然后在intersperse 函数中使用\n。我会试试看。
  • 我已经发布了一个答案,其中穿插了",\n"。我想这就是你想要的。

标签: elixir anonymous-function


【解决方案1】:

语法错误可以通过添加&1作为部分应用语法的第一个参数来修复:

|> (fn l ->[?[, Enum.map(l, &([inspect(&1, limit: :infinity), ?\n])), ?]] end).()

此代码不包含分隔逗号。为此,如果您想继续制作 iolist,我建议使用 Enum.intersperse

iex(1)> [1, 2, [3], [4, 5]] |> (fn l ->[?[, Enum.map(l, &inspect(&1, limit: :infinity)) |> Enum.intersperse(",\n"), ?]] end).() |> IO.puts
[1,
2,
[3],
[4, 5]]

为了便于阅读,我还将其分成多行:

[1, 2, [3], [4, 5]]
|> (fn list ->
  elements = Enum.map(list, &inspect(&1, limit: :infinity)) |> Enum.intersperse(",\n")
  [?[, elements, ?]]
end).()
|> IO.puts

【讨论】:

  • 您能否解释/读出原始 Enum.map 的第二个参数:&(&1, [inspect(limit: :infinity), ?\n])。在我看来,一个函数接受它的第一个参数,检查它并将新行连接到它。它周围的方括号是否意味着“列出序列”?外面的“&”是做什么的?它似乎也是一个函数。
  • 糟糕,我的回答有误。我现在已经修好了。 &([inspect(&1, limit: :infinity), ?\n]) 是一个较短的语法,因此等同于:fn x -> [inspect(x, limit: :infinity), ?\n] end。如果这还不能说明一切,请告诉我。
  • 周围的方括号是否意味着函数的结果变成了一个列表?如果inspect 和换行符不在括号中,那么评估的类型似乎会有所不同。我更习惯于程序语言的明确性
  • 是的,& 启动匿名函数。最外面的括号也是可选的,例如&[&1, &1]fn x -> [x, x] end 相同。
  • (&File.write('output.txt',&1)).() 中的& 怎么样?它似乎没有使表达式成为匿名函数。
猜你喜欢
  • 2021-10-05
  • 2014-08-01
  • 1970-01-01
  • 2012-01-26
  • 1970-01-01
  • 1970-01-01
  • 2013-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多