我正在尝试通过返回双选项而不是双精度来编写一些处理错误的函数。其中许多函数互相调用,因此将双选项作为输入来输出其他双选项。问题是,我不能用双选项做什么,我可以用双打做 - 简单的事就是用'+'添加它们。
例如,一个分为两个双精度数的函数,并返回一个带有none的双选项,用于除以零错误。然后另一个函数调用第一个函数并为其添加另一个双选项。
请告诉我是否有办法,或者我完全误解了F#选项类型的含义。
答案 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,原因有两个: