我在OCaml中有以下功能:
let get_all_parents lst =
List.map (fun (name,opt) -> opt) lst
使用(name, opt)
将我的大列表映射到opt
列表。一个选项可以包含None
或Some value
,在这种情况下是一个字符串。我想要一个包含所有值的字符串列表。
我是初学者学习OCaml。
答案 0 :(得分:0)
我要扩大@ Carsten的答案。他指的是正确的方向。
不清楚你问的问题是什么。例如,我不确定您为什么要告诉我们您的功能get_all_parents
。可能这个功能是你试图得到你想要的答案,而且它并不适合你。或者您可能对此功能感到满意,但您想对其结果进行进一步处理吗?
无论哪种方式,List.map
都无法完成整个工作,因为它总是会返回与其输入长度相同的列表。但是你需要一个可以有不同长度的列表,具体取决于大列表中有多少None
个值。
所以你需要一个只能提取你感兴趣的列表部分的函数。正如@Carsten所说,关键函数是List.filter
。
map
和filter
的某种组合肯定会做你想要的。或者您可以使用fold
,它具有map
和filter
的强大功能。或者你可以编写自己的递归函数来完成所有的工作。
<强>更新强>
也许您的问题在于从string
中提取string option
。 &#34;很好&#34;这样做的方法是提供一个默认值,当选项为None
时使用
let get default xo =
match xo with
| None -> default
| Some x -> x
# get "none" (Some "abc");;
- : string = "abc"
# get "none" None;;
- : string = "none"
#
答案 1 :(得分:0)
我认为filter
和map
一起使用是一个很好的解决方案。这是因为当您应用map
将string option
转换为string
时,您需要处理None
个案。即使你知道你没有任何None
因为filter
将它们删除了,类型检查器也不会,也无法帮助你。如果您启用了非穷举模式匹配警告,您将获得它们,或者您必须为None
情况提供某种虚拟字符串。并且,您将不得不希望在以后重构时不会引入错误,或者编写测试用例或进行更多代码审查。
相反,您需要一个函数filter_map : ('a -> 'b option) -> 'a list -> 'b list
。我的想法是,这与map
类似,但filter_map f lst
会将lst
评估为f
的{{1}}的每个元素都删除。如果None
评估为f
,则结果列表将为Some v
。然后你可以像v
这样使用:
filter_map
您也可以将其写为
filter_map (fun (_, opt) -> opt) lst
更一般的例子是:
filter_map snd lst
filter_map (fun (_, opt) ->
match opt with
| Some s -> Some (s ^ "\n")
| None -> None)
lst
可以像这样实现:
filter_map
编辑为了更完整,您也可以
let filter_map f lst =
let rec loop acc = function
| [] -> List.rev acc
| v::lst' ->
match f v with
| None -> loop acc lst'
| Some v' -> loop (v'::acc) lst'
in
loop [] lst
遗憾的是,这种功能不在标准库中。它出现在Batteries Included和Jane Street Core中。
答案 2 :(得分:0)
str.encode(ciphertext, encoding='utf-8')
结果:
type opt = Some of string | None
List.fold_left (fun lres -> function
(name,Some value) -> value::lres
| (name,None) -> lres
) [] [("s1",None);("s2",Some "s2bis")]