将选项类型列表缩减为仅非元素的最佳方法?

Ton*_*son 62 f# functional-programming

从一个选项列表到一个只包含Some的元素的列表,我出乎意料地遇到了一些麻烦.

我最初的尝试是:

    let ga = List.filter (fun xx ->
        match xx with
        | Some(g) -> true
        | None -> false) gao 
Run Code Online (Sandbox Code Playgroud)

但是,当然,这种结果类型仍然是一个选项列表.我不知道如何使用List.map来压缩它,因为你必须处理匹配语句中的所有情况.我有一个丑陋的解决方案,但我想知道是否有更好的东西.

丑陋:

    let rec gOptRemove gdec gacc = 
        match gdec with 
        | head :: tail -> 
            match head with 
            | Some(a) -> gOptRemove tail (a :: gacc)
            | None -> gOptRemove tail gacc
        | [] -> gacc
Run Code Online (Sandbox Code Playgroud)

我更愿意找到一个非递归的解决方案或找出这种事情的标准方法.

Bri*_*ian 129

只是

List.choose id
Run Code Online (Sandbox Code Playgroud)

如在

> [Some 4; None; Some 2; None] |> List.choose id;;
val it : int list = [4; 2]
Run Code Online (Sandbox Code Playgroud)

List.choose

ID

  • 嗯,作为一个旁边,这似乎是我在stackoverflow上的第1000个答案.我希望这是值得的.:) (15认同)
  • 让这些类型指导你.你想要一个在其签名中包含`option`但只返回`list`(不是选项列表)的函数.看看API(http://msdn.microsoft.com/en-us/library/ee353738.aspx),并且只有一个这样的功能,`选择`,现在你已经95%了. (11认同)
  • ......哇,这很聪明.这是你的大脑一直在思考的方式吗? (4认同)
  • 哇,这很容易.不知道功能是否存在. (2认同)
  • 这样做的原因是:List.choose 想要将“a”变成“b 选项”。`id` 适合于此,因为它将 `'c option` 转换为 `'c option`。 (2认同)