缺點似乎並不像我在第二個示例中所期望的那樣工作。我錯過了什麼?Haskell的工作方式如何工作:
這裏cons將一個元素添加到列表中,這非常棒。
1:[2,3]
但是這一個似乎把第一個元素到列表x和尾到列表的xs:
let { myInt :: [Int] -> [Int] ; myInt (x:xs) = xs }
我真的不明白爲什麼會發生這種事,是事用遞歸做什麼?
在此先感謝!
缺點似乎並不像我在第二個示例中所期望的那樣工作。我錯過了什麼?Haskell的工作方式如何工作:
這裏cons將一個元素添加到列表中,這非常棒。
1:[2,3]
但是這一個似乎把第一個元素到列表x和尾到列表的xs:
let { myInt :: [Int] -> [Int] ; myInt (x:xs) = xs }
我真的不明白爲什麼會發生這種事,是事用遞歸做什麼?
在此先感謝!
的:
操作可用於兩個構建列表和解構名單,取決於你在哪裏使用它。如果您在表達式中使用它,就像您所說的那樣,它用於構建列表。當你在一個模式中使用它時,它會做相反的事情 - 它解構(分解)一個列表。
構建列表:
λ> 1:2:[3, 4]
[1,2,3,4]
解構列表:
λ> let first:second:rest = [1, 2, 3, 4]
λ> first
1
λ> second
2
λ> rest
[3, 4]
這同樣適用於在Haskell許多數據構造。您可以使用Just
構造一個Maybe
值。
λ> let name = Just "John"
λ> :type name
name :: Maybe [Char]
但是,您也可以使用它來分解Maybe
值。
λ> let Just x = name
λ> x
"John"
請注意,這裏沒有關於「:」的任何「特別」 _all_值構造函數具有此屬性。 – MathematicalOrchid
這裏發生了兩件不同的事情。您的第一個示例使用(:)
運算符從元素1
和列表[2,3]
中創建一個新列表。
1:[2,3]
你的第二個例子使用模式匹配。表達...
myInt (x:xs) = ...
...實際上是說「如果myInt
參數包括預先考慮到(可能爲空)列表中的一個元素,那麼讓我們把第一個元素x
和列表xs
。」這個例子可能更清楚:
λ> let { myInt :: [Int] -> String ; myInt (x:xs) = "The first element is " ++ show x ++ " and the rest of the list is " ++ show xs}
λ> myInt [1,2,3]
"The first element is 1 and the rest of the list is [2,3]"
注意,如果輸入列表中包含至少一個元素,這隻會工作。
λ> myInt []
"*** Exception: <interactive>:9:34-127: Non-exhaustive patterns in function myInt
然而,在輸入列表爲空,這樣我們就可以處理這種情況:
λ> let { myInt :: [Int] -> String ; myInt (x:xs) = "The first element is " ++ show x ++ " and the rest of the list is " ++ show xs; myInt _ = "empty list"}
λ> myInt []
"empty list"
這是很好的記住haskell98允許*綴*類型構造,必須以「':'」開頭,所以列表利弊的構造方法(需要兩個參數)是這個一般規則的稍微特殊情況。 – jberryman