制作将“列表”与“选项列表”分开的辅助函数

Making helper function that separates 'a list from 'a option list

我正在尝试创建一个辅助函数,它可以采用 [Some 3; None;大约 5 个; Some 10] = [3;5;10] 并只输出整数,如图所示。但是我遇到了解析错误,不知道该怎么办。

apfold.ml”,第 32 行,字符 11-12: 解析错误:[opt_when_expr] 预计在 [patt_as_patt_opt] 之后(在 [match_case0]

行号是指带|的行[一些] [int] = [int]

到目前为止的函数是这样的:

let rec difference (thelist:'a option list) : 'a list =
    match thelist with
    | [Some] [int] -> [int]
;; 

功能差异被插入到这里:

let deoptionalize (lst:'a option list) : 'a list =
    List.filter ~f:(fun lst -> difference)
;;

尽管如此,如果有一种方法可以在不使用辅助函数的情况下执行 deoptionalize 函数,我将非常感谢任何帮助解决这个问题。

感谢 Jeffrey Scofield 和我自己的一些想法,我们确定一个很好的方法是使用 List.map 和 List.filter 将 None 与 Some 分开然后从内部提取 int。内部函数可以是辅助函数或内联函数;这是一种风格偏好。

您的错误来自 [Some] [int]:这不是有效的 OCaml 模式。

关于使用 List.filter 然后 List.map,遍历列表两次是很没用的。您可以只使用 List.fold_right:

let remove_options l = List.fold_right
    (fun x result ->
     match x with
     | Some i -> i :: result
     | None -> result )
    l []

这样您就可以遍历列表一次并避免分配中间列表。

从 OCaml 4.08 版开始,现在可以通过组合标准库中的 List.filter_map (doc) and Fun.id (doc) 函数轻松完成此操作:

List.filter_map Fun.id [Some 3; None; Some 5; Some 10];;

(* returns [3; 5; 10] *)

相关问题,如果使用 Base/Core 库:ocaml - deoptionalize a list: is there a simpler way?