2017-09-12 72 views
1
的使用

我只是想知道,遞歸例如:哈斯克爾::斗拱的遞歸

squaresRec :: [Double] -> [Double] 
squaresRec [] = []      
squaresRec (x:xs) = x*x : squaresRec xs 

爲什麼在遞歸的情況下,沒有括號?它不應該是這樣的:

squaresRec :: [Double] -> [Double] 
squaresRec [] = []      
squaresRec [x:xs] = x*x : squaresRec xs 

我知道這是行不通的。但只是想知道背後的解釋。

回答

5

[]與空列表匹配。

[1]與僅包含一個元素的列表匹配,並且該列表必須是等於1的數字。請注意,[1]實際上是(1:[])的語法糖,即它真正匹配的是:以1開頭的列表,後面跟着一個空列表......這只是一種複雜的方式,表示「包含單個元素的列表1「。

(x:xs)匹配以x開頭的列表,隨後xs(以及可能包含任何數量的元素,可能爲零)。即此模式匹配任何與至少有一個元素的列表。再次

[x:xs]比賽包含正好一個元素的列表,而這個元素應該匹配模式(x:xs)。 (即使按類型,這也沒有意義,因爲你的列表包含Double-數字,而不是列表。)

+0

我認爲它代表一個元組和一個列表,我對(1,2,3)與[1,2,3]的使用相混淆。 我確實認爲爲什麼不這樣做[(x:xs)]?它是一個不爲空[]的列表,但列表以x開始,其餘爲xs。 –

+0

你可以寫'[(x:xs)]',但括號在那裏沒有任何區別。一般來說,括號隻影響代碼的_parsed_,但[']'已經將一切內容解析到一個AST節點中,所以不管你寫'[x:xs]'還是'[(x :(xs)]'或甚至類似'(([((((x):((xs)))))]))''。方括號OTOH確實有所作爲,即它們觸發語法解析。 '[x:xs]'是'(x:xs):[]'的糖,而'x:xs'已經脫糖。 – leftaroundabout

+2

括號不是元組的構造函數。他們在這裏隔離幾個','(逗號),它們是真正的元組構造者 – Uniaika

3

我有同樣的問題,因爲我來自Erlang。

需要理解的是,我們在Erlang中的[head | tail]模式實際上是由Haskell中的cons函數翻譯的,它是:運算符。圓括號只是在這裏隔離函數參數,就像(3 + 4)那樣。

我知道這很誘人,問「爲什麼???」並且它在視覺上更有意義,但:是我們如何構建(並在模式匹配時分開)鏈表的頭部和尾部。

+1

它似乎確實使得「視覺感覺「對很多人來說,但我從來不明白爲什麼。我覺得更直觀的是,方括號內的所有內容都是單個_elements_,而不是列表。特別是,我發現Matlab慣例可以表示''a b''完全可以表示'a ++ b'。 – leftaroundabout

+0

呃,Erlang是我的第一個編程語言,所以我就是這樣學習列表和理解列表的。對我來說,方括號表示列表的可視上下文,您可以在其中執行諸如缺點和列表推導等內容。 – Uniaika