对F#期权类型执行计算
我试图编写一些函数,通过返回double选项而不是double来处理错误。许多函数相互调用,因此将双选项作为输入输出其他双选项。问题是,我不能用double选项做我能用double做的事情——像用“+”添加它们这样简单的事情 例如,一个函数,它将两个double除法,并返回一个double选项,其中“无”表示“除以零”错误。然后另一个函数调用第一个函数并向其添加另一个double选项对F#期权类型执行计算,f#,options,F#,Options,我试图编写一些函数,通过返回double选项而不是double来处理错误。许多函数相互调用,因此将双选项作为输入输出其他双选项。问题是,我不能用double选项做我能用double做的事情——像用“+”添加它们这样简单的事情 例如,一个函数,它将两个double除法,并返回一个double选项,其中“无”表示“除以零”错误。然后另一个函数调用第一个函数并向其添加另一个double选项 请告诉我是否有办法做到这一点,或者我是否完全误解了F#选项类型的含义。这称为提升-您可以编写函数,通过两个选项提
请告诉我是否有办法做到这一点,或者我是否完全误解了F#选项类型的含义。这称为提升-您可以编写函数,通过两个选项提升另一个函数:
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
最后,我意识到我真正想要的是Option.get函数,它只接受一个'a选项并返回一个'a'。通过这种方式,我可以进行模式匹配,并返回所需的值。
liftA2
如上所述,将提供一种通用方法,将使用double
参数的任何函数“提升”到可以使用double选项的函数
但是,在您的情况下,您可能需要自己编写特殊函数来处理您提到的边缘情况
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
您可以像这样使用这些函数
Some(2.0) <+> Some(3.0) // will give Some(5.0)
Some(1.0) </> Some(0.0) // will give None
在此情况下,您可能需要考虑选项上的零写,原因有两个:
- 空值是值类型,而选项是引用类型。如果您有大量这些双精度的集合,那么使用Nullables将使这些数字保留在堆栈上,而不是放在堆上,这可能会提高您的性能
- Microsoft提供了一系列内置函数,允许您直接对空值执行数学运算,这与您尝试对选项执行的操作完全相同
尝试添加一些代码示例,说明您想要实现什么,以及您得到了什么错误一些(1.0)+一些(1.0)不起作用。如果它真的不起作用,那么我就不能真正使用它,因为我有很多函数接受双选项并返回双选项,它们都依赖于彼此来做一些计算。你要找的是一个选项工作流。看一看……或者使用just use选项。bind
。也许这会有帮助:您可以更进一步,使代码更具可读性:在此处定义liftOpt,然后(非常、非常局部地)使用类似于let(+)o1 o2=liftOpt(+)o1 o2
的方法对+
进行阴影处理。现在您可以编写让x,y=3.0,2.0,然后x+y
@DanielFabian好的提示,最好的地方(IMO)是将提升的(+)
放在模块选项中,扩展默认的选项。然后,只有在打开选项
之后,才能在范围内解除(+)
)
Some(2.0) <+> Some(3.0) // will give Some(5.0)
Some(1.0) </> Some(0.0) // will give None
let liftOpt2 f =
(function a b ->
match (a, b) with
| (Some (a), Some (b)) -> f a b |> Some
| _ -> None)