从 Ocaml 列表列表中删除所有空列表

Remove all empty lists from a list of lists Ocaml

请帮忙。 我正在尝试在 OCaml 中编写两个非递归函数(列表列表包含列表本身的元素)

  1. clear l 以列表列表作为参数,returns 列表列表没有空列表(如果有的话)。 示例:clear [[2];[];[];[3;4;6];[6;5];[]] 将 returns [[2];[3;4;6];[6;5]]
  2. sort_length l 根据长度对列表 l 的元素进行排序。例如。 sort_length [[2];[];[3];[6;5]] returns [[];[2];[3];[6;5]]

我只能使用这些预定义函数:List.filter、List.sort、List.hd、List.tl、List.length,不能使用其他函数。 谢谢

对于第二个功能,到目前为止我已经尝试过了,但是我使用了 map 这是不允许的

let rec insert cmp e = function
  | [] -> [e]
  | h :: t as l -> if cmp e h <= 0 then e :: l else h :: insert cmp e t
  
let rec sort cmp = function
  | [] -> []
  | h :: t -> insert cmp h (sort cmp t)

let sort_length l =
  let l = List.map (fun list -> List.length list, list) l in
  let l = sort (fun a b -> compare (fst a) (fst b)) l in
  List.map snd l;; 

谢谢

如此处所述:https://ocaml.org/api/List.html#VALfilterList.filter returns 列表中满足给定谓词的所有元素。因此,您必须编写一个描述非空列表的谓词。表示列表不为空的另一种方式是说“它的大小大于零”。所以可以这样表述clear

let clear list = 
  let is_not_empty l = (List.length l) > 0 in
  List.filter is_not_empty list

Small edit

As mentioned by Chris Dutton, using List.length may be inefficient. Another approach would be to express is_not_empty in this way:

 let is_not_empty = function 
 | [] -> false 
 | _  -> true

This approach is "better" because it does not require going through the whole list to see if it is empty or not.

第二点,List.sort函数对两个元素('a -> 'a -> int)进行比较,这里的比较必须作用于列表的大小

换句话说,必须比较观察到的两个列表的大小。一种方法是对两个观察列表的大小使用 Int.compare (https://ocaml.org/api/Int.html#VALcompare)。例如:

let sort_length list = 
  let compare_length a b = 
     let la = List.length a in 
     let lb = List.length b in 
     Int.compare la lb
   in 
   List.sort compare_length list

这两个函数有更简洁的写法,但这些实现应该相当清楚。