繁体   English   中英

试图理解OCaml中的这段代码

[英]Trying to understand this block of code in OCaml

我试图了解这段代码正在做什么:

let rec size x =
    match x with
      [] -> 0
    | _::tail -> 1 + (size tail) ;;

我知道这个表达式计算列表的大小,但我不明白它在代码中的位置逐一减少了列表。 例如,我认为它需要从[1; 2; 3]到[2; 3]到[3],但是在哪里或如何做到这一点? 我不明白。

谢谢。

OCaml中的列表是使用空列表( [] )和cons( :: :)构造函数递归构建的。 所以[1; 2; 3] [1; 2; 3] [1; 2; 3]1::2::3::[]的句法糖。

通过使用模式_::tail_表示我们忽略列表的头部)并在tail调用相同的函数size来减少每个步骤中的x来计算size 当列表为空并且[]的模式成功时,该函数最终终止。

这是一个如何size [1; 2; 3]的简短说明size [1; 2; 3] size [1; 2; 3] size [1; 2; 3]计算:

   size 1::2::3::[]
~> 1 + size 2::3::[] // match the case of _::tail
~> 1 + 1 + size 3::[] // match the case of _::tail
~> 1 + 1 + 1 + size [] // match the case of _::tail
~> 1 + 1 + 1 + 0 // match the case of []
~> 3

作为旁注,您可以从图中看到,需要将大量信息存储在堆栈中以计算size 这意味着如果输入列表很长,您的函数可能会导致堆栈溢出错误,但这是另一个故事。

根据这篇文章 ,实际上你正在讨论这个例子:

正如我们所看到的,列表可以是空的(列表是[]形式),或者由第一个元素(它的头部)和一个子列表(它的尾部)组成。 该列表的格式为h::t

如果列表匹配空列表或使用模式匹配来提取头(第一项)和尾(所有其他项),则提供的语句简单地给出0,然后使用递归来获得尾部的长度。

因此,它是减少列表的_::tail ,以及计算大小的1 + (size tail) |之前的位 当然,这是递归的终止条件。

如果被视为:可能更容易理解(在我看来)

let rec size x = match x with
            []  ->  0
    |  _::tail  ->  1 + (size tail)
    ;;

(这实际上非常类似于链接页面中使用的格式,我只是略微改变它以排列->符号)。

实际上,这段代码使用模式匹配的功能来计算列表的大小。

match意味着您将尝试使x以下列模式之一进入。

第一个[]意味着你的列表是空的,所以它的大小是0.而第二个_::tail意味着你有一个元素(*),后面是列表的其余部分,所以基本上大小是1 + size(rest of the list)

(*)下划线表示您不关心此元素的值。

每当你匹配一个列表时,你可以匹配形式head::tail的模式,其中head将获得第一个元素的值, tail将获得余数。 此模式将匹配任何非空列表,因为tail可以为空,但head必须存在。

第二,你在Ocaml中匹配的任何模式,如果你愿意,你可以用下划线替换一个变量来说“匹配这里的东西,但我不打算实际使用它,所以我不给它起个名字”。 所以,在这个程序中,而不是写head::tail -> 1 + (size tail) ,它们写_::tail -> 1 + (size tail)因为它们实际上并没有使用第一个元素,只是确保它存在。

它使用模式匹配来提取列表的尾部(将其命名为tail ),然后使用尾部调用自身。 也许缺少的部分是模式匹配。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM