Elixir 列表连接

标签 elixir

所以我一直在玩 Elixir,对一些事情有点困惑:

iex> [ 1 | [ 2 ] ] // [ 1, 2] (expected)
iex> [ 1 | 2 ] // [ 1 | 2 ] (huh?)

我的困惑是为什么第二个版本会这样做。我了解 2不是一个列表,所以它不能将“头”与“尾”连接起来,但是,在我看来,当尾不是一个列表时,它应该会抛出一个错误。我一直在想一个有这种行为的用例,但空手而归。如果有人能解释为什么这是理想的行为,我将不胜感激。谢谢!

最佳答案

列表的尾部实际上可以是任何术语,而不仅仅是另一个列表。这有时被称为“不当列表”。

Erlang 文档 gives an example关于如何使用它来构建无限列表,但您不太可能在野外遇到这种情况。这个想法是,在这种情况下,尾部不是一个列表,而是一个函数,它将返回另一个不正确的列表,其中包含下一个值和函数:

defmodule Lazy do
  def ints_from(x) do
    fn ->
      [x | ints_from(x + 1)]
    end
  end
end

iex> ints = Lazy.ints_from(1)
#Function<0.28768957/0 in Lazy.ints_from/1>

iex> current = ints.()
[1 | #Function<0.28768957/0 in Lazy.ints_from/1>]

iex> hd(current)
1

iex> current = tl(current).()
[2 | #Function<0.28768957/0 in Lazy.ints_from/1>]

iex> hd(current)
2

iex> current = tl(current).()
[3 | #Function<0.28768957/0 in Lazy.ints_from/1>]

iex> hd(current)
3

但是,我们可以使用 Stream 在 Elixir 中更轻松地实现无限流。模块:
iex> ints = Stream.iterate(1, &(&1+1))
#Function<32.24255661/2 in Stream.unfold/2>

iex> ints |> Enum.take(5)
[1, 2, 3, 4, 5]

不正确列表的另一个(伪)用例是所谓的 iodatachardata值(value)观。这些允许您优化需要频繁附加到 charlist(单引号字符串)的情况,因为 charlist 是链表,附加成本很高。您通常也不会在野外看到带有 chardata 的不正确列表,因为我们可以只使用常规列表 - 但请放心,它们可以用于构建 chardata。如果你想了解更多关于chardata的知识,我推荐this blog post from The Pug Automatic .

关于Elixir 列表连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34784320/

相关文章:

erlang - 如何在 Elixir 中找到进程开始的位置

elixir - 什么是组长

elixir - 如何重新加载 ecto 记录?

sockets - Phoenix Channels - 每个插槽有多个 channel

csv - Elixir:尝试将映射写入 CSV,被写入为流结果

recursion - 如何在 Elixir 中模拟 Ruby 的 until 循环?

elixir - 如何在主机重启的情况下自动重启 phoenix?

polymorphism - 如何在 Elixir 中实现函数/进程多态性

elixir - Phoenix Code_Reloader 是否只重新加载 Elixir 代码?

elixir - 将字符码的二进制转换为清晰的字符串?