我已经写了一个函数来取消整数列表,我想知道是否有更好的方法来编写它。
let deoptionalize (lst:'a option list) : 'a list =
List.map ~f:(fun x -> match x with Some x -> x | None -> assert false)
(List.filter ~f:(fun x -> x <> None) lst)
;;
在我正在使用的作业中,使用地图和过滤器是必须的。
答案 0 :(得分:4)
我认为“手动编码”解决方案(即没有map
和filter
)更容易阅读,但如果您真的需要使用它们,请转到:
您似乎正在使用Core
库。如果是这样,我认为你的解决方案并不是那么糟糕,但可以写得更紧凑:
let deoptionalize lst =
List.filter ~f:(is_some) lst
|> List.map ~f:(function | Some x -> x | None -> assert false)
如果您不介意警告(我不鼓励您这样做),您甚至可以省略更多:
let deoptionalize lst =
List.filter ~f:(is_some) lst
|> List.map ~f:(fun (Some x) -> x)
实际上,Core
提供了filter_map
(感谢@Ramon Snir的提示),它结合了两者,因此您可以使用:
let deopt lst =
List.filter_map ~f:(fun x -> x) lst;;
答案 1 :(得分:2)
在你的情况下,我更喜欢这样做:
let deoptionalize l =
let rec deopt acc = function
| [] -> List.rev acc
| None::tl -> deopt acc tl
| Some x::tl -> deopt (x::acc) tl
in
deopt [] l
它更清晰,尾递归,性能更好
答案 2 :(得分:0)
另一种解决方案,
let deoptionalize l =
List.concat @@ List.map (function | None -> [] | Some x -> [x]) l