我不明白Haskell如何将数组销毁为元组
例如,为什么能起作用
head :: [a] -> a
head (x:xs) = x
但这不起作用
head :: [a] -> a
head [x:xs] = x
对我来说毫无意义
为什么这能在中工作
head :: [a] -> a head (x:xs) = x
但这不起作用
head :: [a] -> a head [x:xs] = x
对于学习Haskell的人来说,这是一个非常常见的困难来源。在某些情况下,这些看起来相似,但意味着不同的东西:
-
类型
[a]
等价于[] a
,意思是"零个或多个元素的列表的类型,所有元素都具有类型a
"。 -
模式
[p]
等效于p : []
和(:) p []
,意思是"匹配与模式p
完全匹配的一个元素的列表"。
请注意,末尾带有变量的列表模式匹配任何数量的剩余元素,但如果它以"nil"[]
结尾,则它匹配固定数量的元素。以下是一些长度n的列表示例:
xs
-n≥0-大于零元素;任何列表p : xs
-n≥1-一个以上元素;非空列表p₁ : p₂ : xs
-n≥2-两个以上元素p₁ : p₂ : p₃ : xs
-n≥3-&c[]
-n=0——恰好为零元素;空列表[p]
-n=1——正好是一个元素;单例列表[p₁, p₂]
-n=2——正好是两个元素- CCD_ 16-n=3-&c
写入x : xs
与(:) x xs
相同,它匹配一个或多个元素的列表。把它放在括号里(x : xs)
是等价的,这只是因为优先规则:head x : xs
意味着(head x) : xs
,这是一个有效的表达式,但不是一个有效模式。
写入与(x : xs) : []
和(:) ((:) x xs) []
相同的[x : xs]
,正好匹配一个元素的列表([
e]
(,其中该元素匹配一个或多个元素的清单(e=x : xs
(。以下是一些例子:
let { x : xs = [1] } in (x, xs)
的求值结果为(1, [])
,因为:x
:
xs
与1
:
[]
匹配x
=1
xs
=[]
- 这些都是等价的:
[1]
1 : []
(:) 1 []
let { x : xs = [1, 2, 3] } in (x, xs)
评估为(1, [2, 3])
,因为:x
:
xs
与1
:
2 : 3 : []
匹配x
=1
xs
=[2, 3]
- 这些都是等价的:
[1, 2, 3]
1 : [2, 3]
1 : 2 : [3]
1 : 2 : 3 : []
(:) 1 ((:) 2 ((:) 3 []))
let { x : xs = "hi" } in (x, xs)
评估为('h', "i")
,因为:x
:
xs
与'h'
:
'i' : []
匹配x
='h'
xs
="i"
- 这些都是等价的:
"hi"
'h' : "i"
'h' : 'i' : []
(:) 'h' ((:) 'i' [])
let { [x : xs] = [[1]] } in (x, xs)
评估为(1, [])
,因为:[
x : xs
]
与[
[1]
]
匹配x
:
xs
与1
:
[]
匹配x
=1
xs
=[]
let { [x : xs] = ["yo"] } in (x, xs)
评估为('y', "o")
,因为:[
x : xs
]
与[
["yo"]
]
匹配x
:
xs
与'y'
:
'o' : []
匹配x
='y'
xs
="o"
x : xs
和[x : xs]
都不匹配空列表[]
[x : xs]
与["ya", "no"]
不匹配,因为x : xs
:
[]
与"ya"
:
"no" : []
不匹配,原因是[]
与"no"
:
[]
不匹配[x : xs]
与[[]]
不匹配,因为x
:
xs
与[]
不匹配
(x:xs)
不是元组,(x, xs)
是2元组的模式。CCD_ 135是CCD_ 136的缩写,其中CCD_。另一个是空列表[]
。
(:)
数据构造函数有两个字段:第一个字段(此处为x
(是指向列表第一项的头,第二个字段(这里为xs
(指向其余元素的列表。因此,这看起来像一个链接列表。
[x:xs]
是[(x:xs)]
的一个短变体,因此它与一个列表列表绑定,其中外部列表包含一个单个元素,该单个元素与(x:xs)
匹配,因此是一个非空列表,其中x
是唯一子列表的第一项,xs
是该子列表的其余元素。