Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对F#期权类型执行计算_F#_Options - Fatal编程技术网

对F#期权类型执行计算

对F#期权类型执行计算,f#,options,F#,Options,我试图编写一些函数,通过返回double选项而不是double来处理错误。许多函数相互调用,因此将双选项作为输入输出其他双选项。问题是,我不能用double选项做我能用double做的事情——像用“+”添加它们这样简单的事情 例如,一个函数,它将两个double除法,并返回一个double选项,其中“无”表示“除以零”错误。然后另一个函数调用第一个函数并向其添加另一个double选项 请告诉我是否有办法做到这一点,或者我是否完全误解了F#选项类型的含义。这称为提升-您可以编写函数,通过两个选项提

我试图编写一些函数,通过返回double选项而不是double来处理错误。许多函数相互调用,因此将双选项作为输入输出其他双选项。问题是,我不能用double选项做我能用double做的事情——像用“+”添加它们这样简单的事情

例如,一个函数,它将两个double除法,并返回一个double选项,其中“无”表示“除以零”错误。然后另一个函数调用第一个函数并向其添加另一个double选项


请告诉我是否有办法做到这一点,或者我是否完全误解了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)