使用F#的可选参数和选项类型

Old*_*vec 14 f# types optional-parameters option

请考虑以下代码:

type Test () =
  member o.fn1 (?bo) = 1
  member o.fn2 (?bo) = o.fn1 bo

  member o.fn3 (?bo) = 1 + bo.Value
  member o.fn4 (?bo) = o.fn3 bo
Run Code Online (Sandbox Code Playgroud)

虽然fn1fn2工作就好了,fn4产生以下错误:

init.fsx(6,30):错误FS0001:这个表达式应该是int类型,但是这里有类型'a option

MSDN声明:

可选参数被解释为F#选项类型,因此您可以通过使用具有Some和None的匹配表达式以常规方式查询它们以查询选项类型.

对我来说,可选参数不会被解释为F#选项类型,否则代码将被编译.此外,我不明白为什么,当我?bofn3工具提示中盘旋时,val bo: int option但只是从外面预期int.我期望一个接受任何东西的行为,int,Some int和None.而作为最后一点,我不明白为什么fn2有效,但却fn4没有.

谢谢你的澄清

Old*_*vec 8

我必须重新考虑正确的答案.基于这个问题(和答案):

传播可选参数

接缝正确的答案如下:

type Test () =
  member o.fn1 (?bo) = 1
  member o.fn2 (?bo) = o.fn1 bo

  member o.fn3 (?bo) = 1 + bo.Value
  member o.fn4 (?bo) = o.fn3 (?bo = bo)
Run Code Online (Sandbox Code Playgroud)

这是一个很好的功能和答案的信用去desco!


Yin*_*Zhu 5

  1. fn2有效是因为fn1不使用它的参数,因此它是通用的'b option

    type Test () =
       member o.fn1 (?bo1) = 1  --> bo1: 'b option, here 'b = 'a option
       member o.fn2 (?bo) = o.fn1 bo  -->bo: 'a option
    
    Run Code Online (Sandbox Code Playgroud)
  2. fn4抱怨传递给的参数fn3应该是一个int,但不是int option因为当你指定参数时,你当然需要传入一个特定的参数。但是您可以选择省略该参数。的定义/类型签名fn3不知道你是否有指定bo,所以它是一个int option. 请注意,您可能有以下用法:

    type Test () =
       member o.fn1 (?bo) = 1
       member o.fn2 (?bo) = o.fn1 bo
    
       member o.fn3 (?bo) = 
       match bo with
         | Some v -> 1 + bo.Value
         | None -> 1
    
       member o.fn4 (?bo) = o.fn3()
    
    Run Code Online (Sandbox Code Playgroud)

您没有为 指定参数fn3,但是当您指定它时,它是一个具体的int,而不是int option

考虑一个带有三个参数的绘图函数:

let plot(?x,?y,?color)
Run Code Online (Sandbox Code Playgroud)

因为参数是可选的,所以可以有以下用法:

plot(data)
plot(y=data)
plot(x=data, color='r')
Run Code Online (Sandbox Code Playgroud)

但不是:

plot(Some data)
plot(y=Some data)
plot(x=Some data, color=Some 'r')
Run Code Online (Sandbox Code Playgroud)

  • 可选参数是一种对图书馆用户友好的语法,但对图书馆作者不友好。你站在图书馆作者的立场来判断这个功能。接口越动态,底层实现的检查就越多。 (2认同)