2016-04-29 41 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作爲它自己的特殊事物,我們可以說,」無是一個列表,你可以通過將單個元素包含到列表中來構建另一個列表。「那是一個相當不錯的歸納數據類型定義。:)