1

我在使用列表并返回选项列表的递归函数时遇到问题。例如一个函数all_except_one

val all_except_one : 'a -> 'a list -> 'a list option = <fun> 

'a从列表中删除第一次出现的位置。如果'a不在列表中,则应返回None

如果没有该选项,我的代码如下所示:

let same_string s1 s2 =
  s1 = s2

let rec all_except_one str str_l =
  match str_l with
  | [] -> []
  | hd::tl -> if same_string hd str
              then tl
              else hd::(all_except_one str tl)

但是每当我尝试添加该选项时,它都会妨碍我进行递归调用。

4

3 回答 3

4

一个option list看起来像[ None; Some "abc"; None ]。我想你想要一个list option,看起来像Some ["a"; "b"; "c"]or None

至于您的主要问题,您必须按案例处理递归调用。如果你的递归调用返回 None 你也会返回 None 。如果递归调用返回 a Some list,您将返回Some (longer list)。我会说,您还需要重新考虑基本情况(当列表为空时)。

于 2013-10-17T23:37:09.643 回答
0

匹配递归调用结果的另一种方法是编写一个带有累加器参数的辅助函数:

let remove_first elt list =
  let rec loop acc = function
    | [] -> None
    | x::xs ->
        if x = elt then Some (List.rev_append acc xs)
        else loop (x::acc) xs in
  loop [] list

这样做的一个小优点是循环变成了尾递归。

于 2013-10-18T08:19:46.447 回答
0

老实说,我不明白你为什么需要same_string功能,什么时候可以使用=

我建议像这样实现你想要的功能:

let rec all_except_one str str_l = match str_l with
  | [] -> None
  | hd :: tl -> if hd = str then Some tl else 
      match all_except_one str tl with
      | None -> None
      | Some x -> Some (hd :: x)

是什么导致您的案例出现问题?

于 2013-10-17T23:50:06.780 回答