2016-04-29 42 views
4

我在深入探究菲尼克斯如何将模板渲染为碘甲烷,并发现了一些对我而言看起来很奇怪的列表。似乎我缺少涉及“竖线”或“垂直管道”字符(|)的列表的基本语法。Elixir:这是什么样的列表还有竖条呢?

下面是一些例子我明白:

# prepends 1 to the list [2, 3] 
l = [1 | [2, 3]] #=> [1, 2, 3] 

# matches the head and tail into variables 
inspect_tail = fn ([_head | tail]) -> IO.inspect(tail) end 

那些我得到。但是这是什么

l = ["hi" | "there"] #=> ["hi" | "there"] 

这似乎是对头部和尾部的名单:

is_list(["hi" | "there"]) #=> true 
hd(["hi" | "there"])  #=> "hi" 
tl(["hi" | "there"])  #=> "there" 

...但如果给这样的列表中length(list)功能给出了ArgumentError

这是什么,它用于什么?

+0

多一点谷歌搜索让我觉得这可能是一个“不当名单” - 是吗? –

+1

仍试图了解用例。正如[本文](http://www.evanmiller.org/elixir-ram-and-the-template-of-doom.html)所示,':re.replace'(与'Regex.replace'不同)返回一个不正确的列表:':re.replace(“sing”,“i”,“o”)#> [“s”,“o”,| “NG”]'。我知道它重用了现有的字符串,但我不明白为什么结果不是'[“s”,“o”,“ng”]' –

回答

5

不正确的列表是正确的。

我会从Learn You Some Erlang引用一个注释,它总结得很好。

注意:使用表格[1 | 2]给出了我们所说的“不正确的列表”。当你以[Head|Tail]的方式进行模式匹配时,不正确的列表将会工作,但不能用于Erlang的标准函数(甚至length())。这是因为Erlang期望正确的列表。正确的列表最后以一个空列表作为其最后一个单元格。在声明像[2]这样的项目时,列表会自动以适当的方式形成。因此,[1|[2]]将工作!不正确的列表虽然在语法上有效,但在用户定义的数据结构之外使用非常有限。

2

这的确是一个不正确的列表中,所谓的,因为不像一个适当的名单,其中有一个头元素和尾巴也是一个列表,不合适的列表中没有,一个列表结束,因为最后一个元素既不是cons也不是零。 (由cons cell/nil verbiage困惑?请参阅结束)

您可以通过登录the inspect tests for an improper list here查看它的实际运行情况。

你会发现,做工精细用它的功能,like hd/1,有只具备作为maybe_improper_list参数类型,而其他国家,like length/1,想到只有一个合适的列表。


如果您没有Lisp背景,那么cons/cell位可能会令人困惑。 “无”基本上是“空列表”,但我觉得这样做会导致对列表的循环定义:“列表要么是绑定到尾部的头元素,它本身就是列表,要么这是空的列表“导致”啧啧,我从来不会猜到一个空的列表是一个列表!感谢您的启发!:rolleyes:“

通过区分nil作为它自己的特殊事物,我们可以说,”无是一个列表,你可以通过将单个元素包含到列表中来构建另一个列表。“那是一个相当不错的归纳数据类型定义。:)