[英]Ocaml take function
我正在尝试创建一个函数,该函数返回列表中前 k 个元素的值。 这是行不通的。 我不知道为什么。
有人可以帮忙吗?
这是 tl 函数 -
let tl j = match j with
| [] -> []
| x :: xs -> xs;;
这才是真正的 take 函数——
let rec take k xs = function
| [] -> failwith "take"
| x :: xs -> if k = List.length ([x] @ xs) then [x] @ xs
else [x] @ take List.length xs (tl(List.rev.xs))
该消息的原因是您遗漏了一对括号,因此您试图将List.length
作为第一个参数传递给take
。
另一个问题是你定义了一个带有三个参数的函数——你的定义说take k xs
返回一个采用列表参数(未命名)的函数。
第三个问题是take (List.length xs) (tl(List.rev xs))
。
这试图从xs
的尾部多取一个元素(并且,出于某种原因,相反)。
所以我要完全重写它。
首先,您不应该为此使用List.length
。
( List.length
几乎从来都不是一个好的解决方案。)
你只需要关心列表是否为空,不管它有多长。
现在,一个更正式的定义:
take k xs
是
k
为 0,则为空列表xs
是空列表,则会出错xs
的头部的列表,其尾部是从xs
的尾部取出k - 1
元素的结果。也就是说,
let rec take k xs = match k with
| 0 -> []
| k -> match xs with
| [] -> failwith "take"
| y::ys -> y :: (take (k - 1) ys)
您的函数接受一个整数n,并且采取n个元素从一个列表中列表,它是包含列表的n个第一元素列表。 所以你的签名很可能是:
int -> 'a list -> 'a list = <fun>
您可能已经猜到该函数将被递归定义,因此您已经可以像这样编写函数的定义:
let rec take n list = ...
您必须构建一个列表,但让我们首先考虑n 的三大类值:
take
一些实现,当给定负数时,尝试有用并从列表的末尾获取n 个元素。 在这里,我们将简单地将任何不是严格为正的 n 视为 if 为 null。N
当我们从列表中取零个元素时,这意味着我们返回空列表:
let rec take n list =
if n > 0
then ...
else [];;
N
现在,我们考虑从列表中取n > 0 个元素的情况。 遵循列表的递归定义,我们必须考虑每种可能的列表,即空列表和非空列表。
let rec take n list =
if n > 0
then
match list with
| [] -> ...
| x :: xs -> ...
else [];;
当我们想从一个空列表中取出n > 0 个元素时会发生什么? 我们失败了。
let rec take n list =
if n > 0 then
match list with
| [] -> failwith "Not enough elements in list"
| x :: xs -> ...
else [];;
现在,递归的一般情况。 我们有一个非空列表,并且n > 0 ,所以我们知道我们可以从列表中取出至少一个元素。 这个值是x
,它构成了我们想要返回的列表的头部。 列表的尾部是由xs的n-1 个元素组成的,它很容易通过take
自身计算:
let rec take n list =
if n > 0 then
match list with
| [] -> failwith "Not enough elements in list"
| x :: xs -> x :: (take (n - 1) xs)
else [];;
您当前的问题是您需要在(List.length xs)
周围(List.length xs)
括号。 该代码还将空输入列表在所有情况下都视为错误,这是不正确的。 如果所需长度k
为 0,则空列表是合法输入。
更新
您的定义中还有一个额外的参数。 如果你这样说:
let myfun k xs = function ...
函数myfun
有 3 个参数。 前两个被命名为k
和xs
,第三个是function
表达式的隐含部分。
快速修复只是删除xs
。
我认为您可能会在递归调用take
要求错误数量的元素。 反正有什么要看的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.