F# 将选项类型列表压缩为非无元素的最佳方法?
从一个选项列表到一个只包含一些元素的列表,我意外地遇到了一些麻烦 我最初的尝试是:F# 将选项类型列表压缩为非无元素的最佳方法?,f#,functional-programming,F#,Functional Programming,从一个选项列表到一个只包含一些元素的列表,我意外地遇到了一些麻烦 我最初的尝试是: let ga = List.filter (fun xx -> match xx with | Some(g) -> true | None -> false) gao 但当然,这种结果类型仍然是“选项列表”。我不知道如何使用List.map来压缩它,因为您必须在匹配语句中处理所有情况。我有一个丑陋的解决办法,但我想知道是否有更好的办法
let ga = List.filter (fun xx ->
match xx with
| Some(g) -> true
| None -> false) gao
但当然,这种结果类型仍然是“选项列表”。我不知道如何使用List.map来压缩它,因为您必须在匹配语句中处理所有情况。我有一个丑陋的解决办法,但我想知道是否有更好的办法
丑陋的:
我更愿意找到一个非递归的解决方案,或者找出这类问题的标准方法。简单地说
List.choose id
如
另一种方法是使用选项模块功能筛选出带有值的选项,然后创建值列表:
let concreteTypeList =
optionTypeList
|> List.filter (fun v -> Option.isSome v)
|> List.map (fun v -> Option.get v)
哇,那很容易。不知道该函数存在。该函数起作用的原因:List.choose希望将
'a
转换为b选项
id
适用于此,因为它将'c选项
转换为'c选项
…哇,这太聪明了。你的大脑一直都是这样思考的吗?就让类型来引导你吧。您希望函数的签名中包含选项
,但只返回一个列表
(不是选项列表)。看看API(),只有一个这样的函数,choose
,现在你已经有了95%的成功率。嗯,顺便说一句,这似乎是我关于stackoverflow的第1000个答案。我希望这是值得的荣誉。:)
> [Some 4; None; Some 2; None] |> List.choose id;;
val it : int list = [4; 2]
let concreteTypeList =
optionTypeList
|> List.filter (fun v -> Option.isSome v)
|> List.map (fun v -> Option.get v)