折叠选项列表

Ove*_*ive 11 f# fold optional

给出一个列表[Some 1; Some 2; Some 3]我想要一个输出Some 6.鉴于列表[Some 1; None]应该产生None.

但我发现它比我想象的要干净得多.

我能想到的最好的就是这个

let someNums = [Some 1; Some 2; Some 3]
someNums 
|> List.reduce (fun st v ->
  Option.bind (fun x ->
    Option.map (fun y -> x + y) st) v )
Run Code Online (Sandbox Code Playgroud)

Fun*_*l_S 10

let lift op a b =
    match a, b with
    | Some av, Some bv  -> Some(op av bv)
    | _, _ -> None

let plus = lift (+)

[Some 1; Some 2; Some 3]
|> List.reduce plus
// val it : int option = Some 6


[Some 1; None]
|> List.reduce plus
// val it : int option = None
Run Code Online (Sandbox Code Playgroud)

折叠

[Some 1; None]
|> List.fold plus (Some 0)
// val it : int option = None

[Some 1; Some 2; Some 3]
|> List.fold plus (Some 0)
// val it : int option = Some 6

[Some 1; None; Some 2] 
|> List.fold plus (Some 0)
// val it : int option = None
Run Code Online (Sandbox Code Playgroud)


Mar*_*ann 6

您可以通过map2为选项值定义函数来完成此操作:

let optionMap2 f x y =
    match x, y with
    | (Some x', Some y') -> Some (f x' y')
    | _ -> None
Run Code Online (Sandbox Code Playgroud)

这将使您能够编写所需的功能:

let sumSome = List.fold (optionMap2 (+)) (Some 0)
Run Code Online (Sandbox Code Playgroud)

例:

> [Some 1; Some 2; Some 3] |> sumSome;;
val it : int option = Some 6
> [Some 1; None; Some 3] |> sumSome;;
val it : int option = None
Run Code Online (Sandbox Code Playgroud)

目前,该optionMap2功能在F#核心库中不可用,但将来可能会成为该Option模块的一部分.

  • 给你另一个答案是好的,我确定你没有看到它 - 你现在得到额外的代表(我猜是因为你的整体统计数据更高)而不是之前几分钟的虚拟相同答案,这有点令人伤心......但那不是关于你的,所以不要担心 (2认同)