Recursion 在OCaml中使用选项和列表

Recursion 在OCaml中使用选项和列表,recursion,ocaml,options,Recursion,Ocaml,Options,我在接受列表并返回选项列表的递归函数中遇到问题。例如,一个函数除一个之外的所有函数: val all_except_one : 'a -> 'a list -> 'a list option = <fun> 但每当我尝试添加该选项时,它就会妨碍我进行递归调用。一个选项列表看起来像[None;一些“abc”;None]。我想您需要一个列表选项,它看起来像一些[“a”;“b”;“c”]或无 至于您的主要问题,您必须按案例处理递归调用。如果递归调用返回None,那么也将返回

我在接受列表并返回选项列表的递归函数中遇到问题。例如,一个函数
除一个之外的所有函数

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

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

一个
选项列表
看起来像
[None;一些“abc”;None]
。我想您需要一个
列表选项
,它看起来像
一些[“a”;“b”;“c”]


至于您的主要问题,您必须按案例处理递归调用。如果递归调用返回None,那么也将返回None。如果递归调用返回一个
Some列表
,您将返回
Some(更长的列表)
。我认为,您还需要重新考虑基本情况(当列表为空时)。

一个
选项列表
看起来像
[None;一些“abc”;None]
。我想您需要一个
列表选项
,它看起来像
一些[“a”;“b”;“c”]


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

老实说,我不明白为什么您需要相同的字符串
函数,而您可以使用
=

我建议实现您想要的功能,如下所示:

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)
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)

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

老实说,我不明白为什么您需要
相同的字符串
函数,而您可以使用
=

我建议实现您想要的功能,如下所示:

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)
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)

是什么导致了您的问题?

对递归调用的结果进行匹配的另一种方法是使用累加器参数编写帮助函数:

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

这样做的一个次要优点是循环变为尾部递归。

对递归调用的结果进行匹配的另一种方法是使用累加器参数编写辅助函数:

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

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

你也应该把有问题的代码放在这里,这样我们就可以看到为什么每次你添加选项时
,它都会妨碍你进行递归调用。
你也应该把有问题的代码放在这里,这样我们就可以看到为什么每次你添加选项时
,当执行递归调用时,它会遇到阻碍
,这非常好,并且接近我试图实现的目标。我就是不知道在代码的“else”部分如何处理该选项。同样的字符串来自一组示例问题,我正试图解决这些问题来自学ocaml。我用它是因为他们说要用它。这些问题是相互影响的,所以我想他们会让我们稍后修改它。好的。另外,如果您想使用equals操作符
=
作为函数(基本上,这就是您在定义
相同的字符串时所做的操作,就像这样),您可以将它括在括号中:
(=)
。这非常好,接近于我试图实现的功能。我就是不知道在代码的“else”部分如何处理该选项。同样的字符串来自一组示例问题,我正试图解决这些问题来自学ocaml。我用它是因为他们说要用它。这些问题是相互影响的,所以我想他们会让我们稍后修改它。好的。另外,如果您想将equals运算符
=
用作函数(基本上,这就是您在像这样定义
相同字符串时所做的操作),您可以将其括在括号中:
(=)