Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 在OCaml中进行模式匹配时如何使用::_List_Functional Programming_Pattern Matching_Ocaml - Fatal编程技术网

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<