F# 我如何投一个“球”;“字符串”;变成一个;选项<;字符串>&引用;

F# 我如何投一个“球”;“字符串”;变成一个;选项<;字符串>&引用;,f#,F#,我有一个函数声明为 let GetLength (value : option<string>) = if value.IsSome then value.Value.Length else 0 如何将a传递给函数GetLength?您不强制转换它。您需要使用Some构造函数: GetLength Some a 接受的答案无法编译,并生成 GetLength Some a;; ^^^^^^^^^^^^^^ 错误FS0003:此值不是函数,无法应用 F#认为您正在构建一

我有一个函数声明为

let GetLength (value : option<string>) = 
    if value.IsSome then value.Value.Length else 0

如何将a传递给函数GetLength?

您不强制转换它。您需要使用
Some
构造函数:

GetLength Some a

接受的答案无法编译,并生成

GetLength Some a;;
^^^^^^^^^^^^^^ 错误FS0003:此值不是函数,无法应用

F#认为您正在构建一个函数
(GetLength Some)
以应用于值
a
。这是因为它是一种函数式语言

正确的形式是

GetLength (Some a);;

括号的另一种选择:

GetLength <| Some a
为此:

let GetLength (value : string option) =
    match value with
    | Some s when s <> null -> s.Length
    | _ -> 0
let GetLength(值:字符串选项)=
匹配值
|当s为空->s.长度时的一些s
| _ -> 0
对于一个F#程序员来说,意义是明确的。要修复您的实现,请执行以下操作:

let GetLength (value : option<string>) = 
    if value.IsSome && value.Value <> null then value.Value.Length else 0
let GetLength(值:option)=
如果value.IsSome&&value.value为null,则value.value.Length为0
结果可能是一样的,但我并不觉得一目了然就能看出发生了什么


如果模式匹配没有引起您的共鸣,那也没关系,但随着逻辑的发展,在简单情况下额外的“成本”往往会被多次弥补。

要回答将
'a
转换为
的一般问题,您不需要编写.IsSome and.Value,取而代之的是使用“匹配”语句。根据今天的一系列问题,您可能会发现阅读和理解这些语句很有用,这为选项类型提供了讲故事的动机。这不会持续很久。为什么有人愿意在3行上输入18个代币,而在一行上使用12个代币就可以得到完全相同的东西呢?我很高兴有人指出F#中的一些不灵活之处。我知道它的功能和所有,但我希望它采取更务实的方法,留下一些纯粹的意识形态。如果我能从语言中添加/删除5或6个功能,它肯定是我最喜欢的。到目前为止,还没有。@sker,你不会相信我为此受到了这么多的抵制。我认为C#fans在获得可选参数时很糟糕,但F#fans对不质疑这一点非常狂热。这真是一个耻辱,因为F#可以比这多得多。这太愚蠢了。显然,任何字符串值都将满足选项的要求。我不应该明确地进行这种转换。@Grauenwolf:在过于严厉地批评之前,花一些时间学习如何编写惯用的F#代码可能是值得的。我想你会发现,虽然它通常不同于典型的C#或VB.NET代码,但事情之所以按原样设计是有原因的……如果你坚持认为选项只是一种类型,那么它就是不一致的。定义它F#库,编译器不会将其视为特例。@Robert:但它应该将其视为特例吗?如果编译器足够聪明,能够看到对于任何变量a,将其转换成某些(a)总是安全的,那么我们会损失什么吗?@Grauenwolf:一个原因是,如果不尝试应用自动转换,类型推断会容易得多。F#也不会自动从int转换为long,即使这是一种安全的加宽转换,原因也是一样的。在某个构造函数中封装您的值有多难?对我来说,在类型推断和一致性方面进行权衡是值得的。我认为这是一个“字符串选项”类型没有被专门处理的特性,我可以自己创建一个类似的类型,并且以完全相同的方式工作。
let GetLength (value : string option) =
    match value with
    | Some s when s <> null -> s.Length
    | _ -> 0
let GetLength (value : option<string>) = 
    if value.IsSome && value.Value <> null then value.Value.Length else 0
let to_option = function
  | null -> None
  | obj -> Some obj