我正在尝试重写这段代码,但是没有“匹配”,只能使用
List.hd
、List.tl
和 List.length
被接受。
有人可以启发我吗?
let rec listes_paires l = match l with
| [] -> []
| x :: r -> if List.length x mod 2 = 0 then (x :: (listes_paires r))
else ((x@x):: (listes_paires r));;
match l with [] -> []
实际上是什么意思? “如果 l
是一个空列表,则返回一个空列表。”您可以通过将长度与 0
进行比较来实现此目的,这相当于一个空列表。
let rec listes_paires l =
if List.length l = 0 then []
else ...
在 else 中,我们现在知道列表至少有一个元素长,因此我们可以安全地使用
List.hd l
和List.tl l
。您可以使用本地 let 绑定将名称 x
和 r
绑定到这些。
注意:
List.length
的复杂度为 O(n),因此在递归函数中使用它效率很低。如果您无法进行模式匹配,那么也许您可以使用List.compare_length_with
。或者正如杰弗里指出的那样,只需测试与空列表的相等性[]
。
顺便说一句,考虑到像
List.hd
和List.tl
这样的函数是如何实现的,具有这种限制的分配有点讽刺。
let hd = function
[] -> failwith "hd"
| a::l -> a
let tl = function
[] -> failwith "tl"
| a::l -> l
作为一个附加选项,如果允许使用异常处理,则可以通过在列表上调用 List.hd
并返回
false
或通过返回
Failure "hd"
处理 true
异常来确定列表在恒定时间内是否为空.
let list_is_empty lst =
try List.hd lst; false
with Failure _ -> true