List 在OCaml中进行模式匹配时如何使用::
我想知道的是List 在OCaml中进行模式匹配时如何使用::,list,functional-programming,pattern-matching,ocaml,List,Functional Programming,Pattern Matching,Ocaml,我想知道的是hd是第一个元素,然后tl是第二个元素,因为当我这样做的时候,我总是得到一个错误,如果tl不是第二个元素,我将如何访问第二个元素非常感谢对hd::tl的深入解释谢谢你否tl不是第二个元素,它是列表的其余部分,并且它具有类型'a list。这里的hd和tl只是变量名,您可以选择绑定到列表的第一个元素以及列表的其余部分(即,绑定到包含除第一个元素以外的所有元素的列表)。您可以选择其他名称,例如,fst::rest。在这种情况下,获取第二个元素就像fst::snd::rest一样简单(或者
hd
是第一个元素,然后tl
是第二个元素,因为当我这样做的时候,我总是得到一个错误,如果tl
不是第二个元素,我将如何访问第二个元素非常感谢对hd::tl
的深入解释谢谢你否tl
不是第二个元素,它是列表的其余部分,并且它具有类型'a list
。这里的hd
和tl
只是变量名,您可以选择绑定到列表的第一个元素以及列表的其余部分(即,绑定到包含除第一个元素以外的所有元素的列表)。您可以选择其他名称,例如,fst::rest
。在这种情况下,获取第二个元素就像fst::snd::rest
一样简单(或者x::y::rest
——名称也不重要)
您尝试使用的是模式匹配。它是某些语言的一个特性,它提供了一种可以轻松解构复合数据结构的机制。其思想是,如果您以与构建数据结构相同的方式解构数据结构,例如
let rec (l:int list) f int list =
match l with
| [] -> []
| hd::tl -> 2+tl
这就是解构
let xs = [1;2;3;4]
事实上,[x;y;…;z]
是更基本语法的语法糖z:[],因此构建[1;2;3;4]
列表的另一种方法是使用以下构造:1::2::3::4:[]
。同样的工作方向相反,例如
let [x1;x2;x3;x4] = xs
现在我们准备好下一步,如果右侧的结构与左侧的结构不匹配,例如
let x1::x2::x3::x4::[] = xs
或
在这种情况下,匹配将失败。在我们的例子中是在运行时。为了防止这种情况,并允许程序员处理其数据结构的所有可能配置,OCaml提供了match
结构,您可以在其中指定值结构的多个变量,并选择第一个匹配的变量,例如
let x::y::z::[] = 1::2::[]
上面的函数只预测最多有三个元素的列表(因为兽人不能超过三个)。但是我们可以。为此,我们将使用以下功能—如果列表模式的最后一个元素不是[]
(即仅与空列表匹配,并指定列表的结尾),而是任何其他元素(即变量),则此变量将绑定到所有元素,例如
let orcish_length xs = match xs with
| [] -> 0
| x :: [] -> 1
| x :: y :: [] -> 2
| x :: y :: z :: [] -> 3
现在,我们预测所有可能的列表模式。然而,这个功能现在过于复杂了(因为精灵正在变得复杂)。现在,让我们最终导出一个正常的、人类可读的长度函数
let rec elvish_length xs = match xs with
| [] -> 0
| x :: [] -> 1
| x :: y :: [] -> 2
| x :: y :: z :: [] -> 3
| x :: y :: z :: leftovers -> 3 + elvish_length leftovers
作为练习,尝试向自己证明此函数预测了所有可能的列表 No
tl
不是第二个元素,它是列表的其余部分,它具有类型'a list
。这里的hd
和tl
只是变量名,您可以选择绑定到列表的第一个元素以及列表的其余部分(即,绑定到包含除第一个元素以外的所有元素的列表)。您可以选择其他名称,例如,fst::rest
。在这种情况下,获取第二个元素就像fst::snd::rest
一样简单(或者x::y::rest
——名称也不重要)
您尝试使用的是模式匹配。它是某些语言的一个特性,它提供了一种可以轻松解构复合数据结构的机制。其思想是,如果您以与构建数据结构相同的方式解构数据结构,例如
let rec (l:int list) f int list =
match l with
| [] -> []
| hd::tl -> 2+tl
这就是解构
let xs = [1;2;3;4]
事实上,[x;y;…;z]
是更基本语法的语法糖z:[],因此构建[1;2;3;4]
列表的另一种方法是使用以下构造:1::2::3::4:[]
。同样的工作方向相反,例如
let [x1;x2;x3;x4] = xs
现在我们准备好下一步,如果右侧的结构与左侧的结构不匹配,例如
let x1::x2::x3::x4::[] = xs
或
在这种情况下,匹配将失败。在我们的例子中是在运行时。为了防止这种情况,并允许程序员处理其数据结构的所有可能配置,OCaml提供了match
结构,您可以在其中指定值结构的多个变量,并选择第一个匹配的变量,例如
let x::y::z::[] = 1::2::[]
上面的函数只预测最多有三个元素的列表(因为兽人不能超过三个)。但是我们可以。为此,我们将使用以下功能—如果列表模式的最后一个元素不是[]
(即仅与空列表匹配,并指定列表的结尾),而是任何其他元素(即变量),则此变量将绑定到所有元素,例如
let orcish_length xs = match xs with
| [] -> 0
| x :: [] -> 1
| x :: y :: [] -> 2
| x :: y :: z :: [] -> 3
现在,我们预测所有可能的列表模式。然而,这个功能现在过于复杂了(因为精灵正在变得复杂)。现在,让我们最终导出一个正常的、人类可读的长度函数
let rec elvish_length xs = match xs with
| [] -> 0
| x :: [] -> 1
| x :: y :: [] -> 2
| x :: y :: z :: [] -> 3
| x :: y :: z :: leftovers -> 3 + elvish_length leftovers
作为练习,尝试向自己证明此函数预测了所有可能的列表
::
被读取为cons
,是列表.cons的中缀版本。在像Ocaml这样的函数式语言中,列表是一个链表,其中,即[e1;e2;e3;e4]
可以简化为如下内容:
let rec length xs = match xs with
| [] -> 0
| x :: xs -> 1 + length xs
基本上,任何列表都可以简化为递归cons
表达式树,这使得递归在Ocaml或类似函数式语言中非常有用。在每个级别上,您都可以将列表缩减为其头部
和尾部
,其中尾部是减去头部的列表,可以进一步缩减,直到最后::[]
。因此,在上面的示例中,您可以递归地减少列表,直到通过模式匹配找到最后一个元素:
cons(::)
/ \
e1 cons(::)
/ \
e2 cons(::)
/ \
e3 cons(::)
/ \
e4 [ ]
请注意,[last]
可以替换为last:[]
和head::tail
替换为List.cons head-tail
重要的是,在任何时候,列表都可以缩减为head::tail<