tim*_*ngy 1 ocaml functional-programming list pattern-matching
let rec (l:int list) f int list =
match l with
| [] -> []
| hd::tl -> 2+tl
Run Code Online (Sandbox Code Playgroud)
我想知道的是hd
第一个元素,然后tl
是第二个元素因为当我这样做时我不断得到一个错误,如果tl
不是第二个元素我将如何访问第二个元素深入解释hd::tl
将非常感谢谢谢
无tl
不是第二个元素,它是列表的其余部分,它的类型为'a list
.这里hd
和tl
是你选择绑定到列表的第一个元素只是变量名,并以列表的其余部分(即,包含除第一个所有元素的列表).您可以选择其他名称,例如fst::rest
.在这种情况下获得第二个元素就像fst::snd::rest
(或者x::y::rest
- 名称无关紧要)一样简单.
您尝试使用的是模式匹配.它是某些语言的一个特性,它提供了一种轻松解构复合数据结构的机制.我们的想法是,如果您以与构建数据结构相同的方式解构数据结构,例如,
let xs = [1;2;3;4]
Run Code Online (Sandbox Code Playgroud)
这是解构
let [x1;x2;x3;x4] = xs
Run Code Online (Sandbox Code Playgroud)
实际上,[x;y;...;z]
对于更基本的语法来说,它是一种语法糖x :: y:: ... :: z :: []
,因此构造[1;2;3;4]
列表的另一种方法是使用以下构造:1::2::3::4::[]
.同样的方向相反,例如,
let x1::x2::x3::x4::[] = xs
Run Code Online (Sandbox Code Playgroud)
现在我们准备下一步,如果右边的结构与左边的结构不匹配,例如,
let [x;y;z] = [1;2]
Run Code Online (Sandbox Code Playgroud)
要么
let x::y::z::[] = 1::2::[]
Run Code Online (Sandbox Code Playgroud)
在这种情况下,匹配将失败.在我们的运行时案例中.为了防止这种情况,并允许程序员处理其数据结构的所有可能配置,OCaml提供了一个match
构造,您可以在其中指定值结构的多个变体,并选择匹配的第一个,例如,
let orcish_length xs = match xs with
| [] -> 0
| x :: [] -> 1
| x :: y :: [] -> 2
| x :: y :: z :: [] -> 3
Run Code Online (Sandbox Code Playgroud)
上面的函数仅预测具有最多三个元素的列表(因为Orcs不能超过三个).但我们可以.为此,我们将使用以下功能 - 如果列表模式的最后一个元素不是[]
(仅匹配且仅与空列表匹配,并指定列表末尾),但其他任何内容(即变量) ),然后这个变量将绑定到所有元素,例如,
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
Run Code Online (Sandbox Code Playgroud)
所以现在,我们预计所有可能的列表模式.但是,该功能现在过于复杂(因为精灵很复杂).现在,让我们最终得出一个普通的,人类可读的长度函数,
let rec length xs = match xs with
| [] -> 0
| x :: xs -> 1 + length xs
Run Code Online (Sandbox Code Playgroud)
作为练习,尝试向自己证明此功能可以预测所有可能的列表.