对F#选项类型执行计算

时间:2015-04-23 18:28:26

标签: f# options

我正在尝试通过返回双选项而不是双精度来编写一些处理错误的函数。其中许多函数互相调用,因此将双选项作为输入来输出其他双选项。问题是,我不能用双选项做什么,我可以用双打做 - 简单的事就是用'+'添加它们。

例如,一个分为两个双精度数的函数,并返回一个带有none的双选项,用于除以零错误。然后另一个函数调用第一个函数并为其添加另一个双选项。

请告诉我是否有办法,或者我完全误解了F#选项类型的含义。

4 个答案:

答案 0 :(得分:10)

这称为提升 - 您可以编写函数来通过两个选项提升另一个函数:

let liftOpt f o1 o2 = 
        match (o1, o2) with
        | (Some(v1), Some(v2)) -> Some(f v1 v2)
        | _ -> None

然后你可以提供应用的功能,例如:

let inline addOpt o1 o2 = liftOpt (+) o1 o2

答案 1 :(得分:3)

如上所述,

liftA2将提供一种通用方法来“解除”对double参数起作用的任何函数,该函数可以处理double option参数。

但是,在您的情况下,您可能必须自己编写特殊功能来处理您提到的边缘情况

let (<+>) a b =
    match (a, b) with
    | (Some x, Some y) -> Some (x + y)
    | (Some x, None)   -> Some (x)
    | (None, Some x)   -> Some (x)
    | (None, None)     -> None

请注意,liftA2不会自动将None添加到Some(x)的情况。

划分的liftA2方法也需要一些特殊的处理,但它的结构通常是我们自己写的

let (</>) a b =
    match (a, b) with
    | (Some x, Some y) when y <> 0.0d -> Some (x/y)
    | _ -> None

您可以使用

这些功能
Some(2.0) <+> Some(3.0) // will give Some(5.0)
Some(1.0) </> Some(0.0) // will give None

另外,严格地说,lift被定义为“高阶函数” - 它接受一个函数并返回另一个函数。

所以它看起来像这样:

let liftOpt2 f =
    (function a b ->
        match (a, b) with
        | (Some (a), Some (b)) -> f a b |> Some
        | _ -> None)

答案 2 :(得分:0)

最后,我意识到我真正想要的是Option.get函数,它只需要一个'a选项并返回'a。这样,我可以模式匹配,并返回我想要的值。

答案 3 :(得分:0)

在这种情况下,您可能需要考虑Nullables而不是Options,原因有两个:

  • Nullables是值类型,而Options是引用类型。如果你拥有这些双打的大量集合,那么使用Nullables会将数字保留在堆栈上而不是将它们放在堆上,这可能会提高你的性能。
  • Microsoft提供了一堆内置的Nullable Operators,可让您直接对nullables执行数学运算,就像您尝试使用选项一样。