Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.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中实现C的空测试的等价物_F# - Fatal编程技术网

F# 在F中实现C的空测试的等价物

F# 在F中实现C的空测试的等价物,f#,F#,我使用了很多这段代码: let inline (||>) (a: 'a option) (b: 'a -> unit) = if a.IsSome then b a.Value 所以我可以做像这样的事情 myData ||> DoSomethingWithIt 无需测试myData是部分还是无,因为有许多函数通常不需要测试选项。这避免了将测试放在函数本身中 我想将其扩展到一种类型的方法,在这种方法中,我可以像C一样: myData?.DoSomethingWithIt 基

我使用了很多这段代码:

let inline (||>) (a: 'a option) (b: 'a -> unit) = if a.IsSome then b a.Value
所以我可以做像这样的事情

myData ||> DoSomethingWithIt
无需测试myData是部分还是无,因为有许多函数通常不需要测试选项。这避免了将测试放在函数本身中

我想将其扩展到一种类型的方法,在这种方法中,我可以像C一样:

myData?.DoSomethingWithIt
基本上取代:

if myData.IsSome then myData.Value.DoSomethingWithIt
加上一些语法糖

但我不知道如何使用运算符,使其能够访问表达式中类型的方法。这在F中可能吗


我也很乐意了解,如果是这样,为什么它可能是个坏主意:

看看Option.iter。它与您的操作员具有相同的签名。

请查看Option.iter。它与运算符具有相同的签名。

这种结构没有类似的语法,但F有其他选择。 最简单的方法是使用library和FSharpx.Option。可能这将允许您使用与选项相关的操作

打开FSharpx.Option 设a=1 让b=也许吧{ 让!v=a 返回v+3 }//b大约是4 设c:int option=None 让d=可能{ 设!v=c return v+3//无法到达此行 }//d是无
这种结构没有类似的语法,但F有其他的选择。 最简单的方法是使用library和FSharpx.Option。可能这将允许您使用与选项相关的操作

打开FSharpx.Option 设a=1 让b=也许吧{ 让!v=a 返回v+3 }//b大约是4 设c:int option=None 让d=可能{ 设!v=c return v+3//无法到达此行 }//d是无
根据DoSomethingWithIt的返回类型,F库提供了一些标准函数,用于处理可转换为运算符的选项

let x = Some 1

let aPrinter a = printfn "%i" a
let add1 a = a + 1

let (|?>) opt f = Option.iter f opt
let (|??>) opt f = Option.map f opt

x |?> aPrinter
let y = x |??> add1
<>你也可以考虑重新定义你的剂量,以部分应用的方式来选择。

let DoSomethingWithIt' = Option.iter DoSomethingWithIt 
let something' = Option.iter (fun (b:B) -> b.DoSomethingWithIt()) //For instance methods
这可能会导致大量的工作,这取决于您处理的函数数量。
最终,你不应该试图掩盖你正在使用选项的事实。通过将某个内容设置为选项,您告诉编译器您不确定它是否存在。它试图通过强迫你们处理“无”的案件来帮助你们。如果在代码中有很多情况下您知道您的选项是一些,那么您的代码中可能存在更大的架构问题,您应该根据dosomething的返回类型尝试取消所有选项,而F库提供了一些标准函数,用于处理可转换为运算符的选项

let x = Some 1

let aPrinter a = printfn "%i" a
let add1 a = a + 1

let (|?>) opt f = Option.iter f opt
let (|??>) opt f = Option.map f opt

x |?> aPrinter
let y = x |??> add1
<>你也可以考虑重新定义你的剂量,以部分应用的方式来选择。

let DoSomethingWithIt' = Option.iter DoSomethingWithIt 
let something' = Option.iter (fun (b:B) -> b.DoSomethingWithIt()) //For instance methods
这可能会导致大量的工作,这取决于您处理的函数数量。 最终,你不应该试图掩盖你正在使用选项的事实。通过将某个内容设置为选项,您告诉编译器您不确定它是否存在。它试图通过强迫你们处理“无”的案件来帮助你们。如果你的代码中有很多情况下你知道你的选项是有的,那么你的代码中可能有一个更大的架构问题,你应该尝试取消所有的选项我相信?。c中的运算符是一种语法糖,它在调用类型的成员之前隐藏检查null的if语句。即使你能按照你的计划去做,我觉得这也会违反FP原则,并可能导致更多的问题

选项模块可能已经包含了您需要的大部分内容。iter函数允许调用选项值上的函数(如果该值存在)

如果您的输入参数可以为null,但不能为options,则可以使用Option.ofObj函数,该函数将参数转换为带有某些选项的选项(如果参数不为null,则为None)

假设函数DoSomethingWithit接受字符串并返回单位:

   let DoSomethingWithIt = //(string -> unit)
       printf "%s; "
例如,您可以使用此更详细的语法来迭代列表中的可空值:

   let lst = [ "data"; "data 2"; null; "data3" ]
   lst
   |> List.iter (fun v -> v |> Option.ofObj |> Option.iter DoSomethingWithIt)
或者,您可以编写Optioni.ofObj和Option.iter DoSomethingWithIt函数,并执行以下操作

   let SafeDoSomethingWithIt = //(string -> unit)
      Option.ofObj >> Option.iter DoSomethingWithIt 
这为您提供了安全的调用:

   let lst2 = [ "data"; "data 2"; null; "data3" ]
   lst2
   |> List.iter SafeDoSomethingWithIt
您可以概括返回单元的函数组合,但不限于

   let makeSafe fn =
      Option.ofObj >> Option.iter fn
然后,您可以创建一系列安全功能:

   let SafeDoSomethingWithIt = makeSafe DoSomethingWithIt 
   
   let safePrint = makeSafe (printf "%s; ")

   //...etc
那么这仍然有效:

   lst2
   |> List.iter SafeDoSomethingWithIt
   
   lst2
   |> List.iter safePrint
还可以使用Option.bind函数为返回值的函数编写包装器

   let makeSafeReturn fn = //(string -> string option)
       Option.ofObj >> Option.bind fn
我相信这个?。c中的运算符是一种语法糖,它在调用类型的成员之前隐藏检查null的if语句。即使你能按照你的计划去做,我觉得这也会违反FP原则,并可能导致更多的问题

选项模块可能已经包含了您需要的大部分内容。iter函数允许调用va上的函数 如果存在该值,则选项的lue

如果您的输入参数可以为null,但不能为options,则可以使用Option.ofObj函数,该函数将参数转换为带有某些选项的选项(如果参数不为null,则为None)

假设函数DoSomethingWithit接受字符串并返回单位:

   let DoSomethingWithIt = //(string -> unit)
       printf "%s; "
例如,您可以使用此更详细的语法来迭代列表中的可空值:

   let lst = [ "data"; "data 2"; null; "data3" ]
   lst
   |> List.iter (fun v -> v |> Option.ofObj |> Option.iter DoSomethingWithIt)
或者,您可以编写Optioni.ofObj和Option.iter DoSomethingWithIt函数,并执行以下操作

   let SafeDoSomethingWithIt = //(string -> unit)
      Option.ofObj >> Option.iter DoSomethingWithIt 
这为您提供了安全的调用:

   let lst2 = [ "data"; "data 2"; null; "data3" ]
   lst2
   |> List.iter SafeDoSomethingWithIt
您可以概括返回单元的函数组合,但不限于

   let makeSafe fn =
      Option.ofObj >> Option.iter fn
然后,您可以创建一系列安全功能:

   let SafeDoSomethingWithIt = makeSafe DoSomethingWithIt 
   
   let safePrint = makeSafe (printf "%s; ")

   //...etc
那么这仍然有效:

   lst2
   |> List.iter SafeDoSomethingWithIt
   
   lst2
   |> List.iter safePrint
还可以使用Option.bind函数为返回值的函数编写包装器

   let makeSafeReturn fn = //(string -> string option)
       Option.ofObj >> Option.bind fn

重写| |>是个坏主意,因为它是用于元组解构的预定义运算符1、2 | |>printfn%d%d,如果有人试图打开您的module@JL0PD,我不知道!感谢您让我知道重写| |>是个坏主意,因为它是用于元组解构的预定义运算符1、2 | |>printfn%d%d,如果有人试图打开您的module@JL0PD,我不知道!谢谢你让我知道这行不通,因为我的想法是让它尽可能简洁,如果我要使用计算表达式,最好对值进行测试,如果测试通过,那么运行代码。这行不通,因为我的想法是让它尽可能简洁,如果我要使用计算表达式,也可以对值进行测试,然后运行代码(如果测试通过)为了提供一点上下文,我正在处理服务器发送的大量消息,这些消息可能/可能不包括一些值,具体取决于更新的数据。因此,虽然我知道类型是可选的,但几乎每一次交互都是在类型为某个的情况下发生的。但是,由于有超过50个字段存在这种情况,我试图隐藏检查。但我没有意识到Option.iter正是我所需要的!在这种情况下,我建议最稳健的解决方案是编写messageClassifier函数,根据字段实际具有值,将每条消息转换为DU中包装的几种类型之一。这可以让你事先排除所有选项,并明确你处理的每一种信息。但组合的数量会爆炸式增长。这是我收到的一条消息的一个例子,源于C。在任何给定的时间,有29个字段,大约一半可能不在json消息中,大约10个字段是必需的。我不能列出所有的组合;或者我遗漏了什么?原则上可能有数十亿个组合,但实际上服务器实际发送的组合可能只有少数。另一个DU的嵌套结构DU也可能是合适的。这种多样性相当高,因为数据遵循金融交易,并且根据自上次以来更改的计算,字段可能存在,也可能不存在,因此服务器希望客户端根据缺少的字段生成增量。当然,我只想处理更新后的数据,所以我不能只是做一个增量然后运行处理。我可以做一些但非常有限的字段分组,但总的来说,它们必须逐个处理。为了提供一点上下文,我正在处理服务器发送的大量消息,这些消息可能/可能不包括一些值,具体取决于更新的数据。因此,虽然我知道类型是可选的,但几乎每一次交互都是在类型为某个的情况下发生的。但是,由于有超过50个字段存在这种情况,我试图隐藏检查。但我没有意识到Option.iter正是我所需要的!在这种情况下,我建议最稳健的解决方案是编写messageClassifier函数,根据字段实际具有值,将每条消息转换为DU中包装的几种类型之一。这可以让你事先排除所有选项,并明确你处理的每一种信息。但组合的数量会爆炸式增长。这是我收到的一条消息的一个例子,源于C。在任何给定的时间,有29个字段,大约一半可能不在json消息中,大约10个字段是必需的。我不能列出所有的组合;或者我遗漏了什么?原则上可能有数十亿个组合,但实际上服务器实际发送的组合可能只有少数。另一个DU的嵌套结构DU也可能是合适的。这种多样性相当高,因为数据遵循金融交易,根据自上次以来发生变化的计算,字段可能存在,也可能不存在,因此 e服务器有点希望客户端根据缺少的字段生成增量。当然,我只想处理更新后的数据,所以我不能只是做一个增量然后运行处理。我可以做一些但非常有限的领域分组,但总的来说,它们大多需要逐个处理