[英]Misunderstanding of the cons operator
這是關於erlang中cons(|)運算符的一般性問題。 我正在參加一個樣本考試並且存在這個問題:
f2([A1, A2 | A1]) ->
{A2, A1};
f2([A, true | B]) ->
{A, B};
f2([A1, A2 | _]) ->
{A1, A2};
f2([_ | B]) ->
[B];
f2([A]) ->
{A};
f2(_) ->
nothing_matched.
我很困惑為什么以下輸入:([[a],[b],a])導致輸出:{[b],[a]}
為什么是這樣? 根據我的理解,如果從列表中的第二個元素(這是空列表,[])的拆分與第一個元素相同,那么輸出將是:A2,A1。 如果第3個元素a成為列表[a],則輸出為:{[a],[b]}。 為什么?
這是因為在正確的列表中[... | ...]
的右側] [... | ...]
運算符應該是一個列表。 左邊的元素是頭元素的附加或提取值,也可以是其他列表,這沒關系。 左側的最后一個元素指向右側。 這意味着在這種情況下,第一個元素與尾部列表匹配
[A1, A2 | A1] = [[a], [b], a] = [[a], [b] | [a]] = [[a], [b]] ++ [a].
你不能寫[a,b,c | d,e,f,g]
[a,b,c | d,e,f,g]
,你只能有一條尾巴。 但是[a,b,c | [d,e,f,g]]
[a,b,c | [d,e,f,g]]
將起作用並且等於[a,b,c,d,e,f,g]
。 這意味着你構造a
值為a
列表元素,它指向值b
列表元素,它指向值c
列表元素,它指向右側(無論如何)。 它的等價物(僅使用沒有逗號的|
運算符)是:
[a | [b | [c | [d | [e | [f | [g]]]]]]]
[a | [b | [c | [d | [e | [f | [g]]]]]]]
。
要理解它,你應該用逗號來思考它。 綁定示例: [El1, El2 | Tail] = [a,b,c,d], [El1 | [El2 | Tail]] = [a,b,c,d].
[El1, El2 | Tail] = [a,b,c,d], [El1 | [El2 | Tail]] = [a,b,c,d].
在兩種情況下, El1 = a, El2 = b
, Tail = [c,d] = [c | [d]] = [c | [d | []]]
Tail = [c,d] = [c | [d]] = [c | [d | []]]
Tail = [c,d] = [c | [d]] = [c | [d | []]]
。
如您所見[[a],[b], a]
表示值[a]
列表元素(值為a
列表元素,指向空列表[]
)指向值[b]
的列表元素它指向值a
的列表元素,該元素指向空列表[]
。
每個正確的列表最后一個元素指向空列表[]
所以確實[a,b,c] == [a,b,c | []].
[a,b,c] == [a,b,c | []].
但是也有不正確的列表,您可以使用非列表作為尾部來構造它們,如[a,b,c | d]
[a,b,c | d]
但這僅在特定情況下有用,並且大多數列表操作無法應用於它們。 使用的一個示例是延遲評估 ,其中tail是函數。
([[a], [b] , a])
將匹配第一個子句f2([A1, A2 | A1]) -> {A2, A1};
。
所以[A1, A2 | A1] = [[a], [b] , a]
[A1, A2 | A1] = [[a], [b] , a]
,你可以得到A1 = [a], A2 = [b]
,重要的是第二個A1
, A1 = [a]
。
操作員| 用於列表的遞歸定義:[A | B]表示將元素A添加到現有列表B.A是結果列表的第一個元素,稱為頭,B是列表的其余部分,稱為尾巴。 B也可以分為頭部和尾部,並且該過程可以繼續,直到尾部等於空列表[]。
您的示例可以用不同的方式編寫:
L = [[a], [b] , a]. % element list representation
L = [[a]|[[b]|[a|[]]]]. % cons list representation
L = [[a],[b]|[a]]. % mixed representation
在最后一個中,您可以識別模式[A1, A2 | A1]
在f2 / 1函數的第一個子句的[A1, A2 | A1]
中,得到結果{A2,A1} = {[b],[a]}
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.