所以这是我在OCaml中玩的合并排序功能。有趣的是代码提供了我所期望的,这意味着,它对列表进行排序。但后来又引发了一些错误。那么有人可以检查我的代码并告诉我发生了什么以及为什么会出现这些错误?我该如何消除它们?我是OCaml的新手,但我真的想知道发生了什么:
(* Merge Sort *)
(* This works but produces some extra error. Consult someone!! *)
let rec length_inner l n =
match l with
[] -> n
| h::t -> length_inner t (n + 1)
;;
let length l = length_inner l 0;;
let rec take n l =
if n = 0 then [] else
match l with
h::t -> h :: take (n - 1) t
;;
let rec drop n l =
if n = 0 then l else
match l with
h::t -> drop (n - 1) t
;;
let rec merge x y =
match x, y with
[], l -> l
| l, [] -> l
| hx::tx, hy::ty ->
if hx < hy
then hx :: merge tx (hy :: ty)
else hy :: merge (hx :: tx) ty
;;
let rec msort l =
match l with
[] -> []
| [x] -> [x]
| _ ->
let left = take (length l/2) l in
let right = drop (length l/2) l in
merge (msort left) (msort right)
;;
msort [53; 9; 2; 6; 19];;
在终端,我得到:
OCaml version 4.00.1
# #use "prac.ml";;
val length_inner : 'a list -> int -> int = <fun>
val length : 'a list -> int = <fun>
File "prac.ml", line 13, characters 2-44:
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
[]
val take : int -> 'a list -> 'a list = <fun>
File "prac.ml", line 19, characters 2-39:
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
[]
val drop : int -> 'a list -> 'a list = <fun>
val merge : 'a list -> 'a list -> 'a list = <fun>
val msort : 'a list -> 'a list = <fun>
- : int list = [2; 6; 9; 19; 53]
#
答案 0 :(得分:1)
编译器告诉您模式匹配并非详尽无遗。事实上,它正在告诉确切地想要看到什么问题。例如,您可以尝试:
drop 2 []
要解决此问题,您需要决定如何处理函数中的空列表。以下是详尽匹配的drop的定义:
let rec drop n l =
if n = 0 then l
else
match l with
| [] -> []
| h::t -> drop (n - 1) t
如果不清楚:您的代码没有说明如何处理空列表。您的匹配仅说明如果列表的格式为h :: t
该怎么办。但是空列表没有这种形式。您需要为匹配项添加[]
个案例。