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

发布于 2024-11-15 15:09:28 字数 838 浏览 4 评论 0原文

考虑以下代码:

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

虽然 fn1fn2 工作正常,但 fn4 会产生以下错误:

init.fsx(6,30): 错误 FS0001: 该表达式的类型应为 int,但此处的类型为“a option”

MSDN 指出:

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

对我来说,可选参数不会被解释为 F# 选项类型,否则代码会编译。此外,我不明白为什么,当我将鼠标悬停在 fn3 中的 ?bo 上时,工具提示显示 val bo: int option 但从外部只期望 <代码>int。我期望一种不接受任何内容、int、Some int 和 None 的行为。最后一点,我不明白为什么 fn2 有效,但 fn4 无效。

感谢您的澄清

Consider the following code:

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

While fn1 and fn2 work just fine, fn4 produces the following error:

init.fsx(6,30): error FS0001: This expression was expected to have type int but here has type 'a option

MSDN states:

Optional parameters are interpreted as the F# option type, so you can query them in the regular way that option types are queried, by using a match expression with Some and None.

To me, optional parameters are not interpreted as the F# option type otherwise the code would compile. Moreover I do not understand why, when I hover over ?bo in fn3 the tooltip says val bo: int option but from outside expects only int. I would expect a behavior of accepting nothing, int, Some int and None. And as the last note, I do not understand why fn2 works but fn4 does not.

Thanks for clarification

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

弄潮 2024-11-22 15:09:28

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

传播可选参数

似乎正确的答案如下:

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)

这是一个简洁的功能,答案请访问 desco

I have to reconsider the correct answer. Based on this question (and answer):

Propagating optional arguments

it seams that the correct answer is the following:

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)

It is a neat feature and credits for the answer go to desco!

笛声青案梦长安 2024-11-22 15:09:28
  1. fn2 之所以有效,是因为 fn1 不使用其参数,因此它是通用的 'b 选项

    类型测试 () =
       成员 o.fn1 (?bo1) = 1 --> bo1: 'b 选项,这里 'b = 'a 选项
       member o.fn2 (?bo) = o.fn1 bo -->bo: '一个选项
    
  2. fn4 抱怨传递给 fn3 的参数应该是 int,而不是 int option 因为当您指定参数时,您的当然需要传入一个特定的。但您可以选择省略该参数。 fn3 的定义/类型签名不知道您是否指定了 bo,因此它是一个 int 选项。请注意,您可能有以下用法:

    类型测试 () =
       成员 o.fn1 (?bo) = 1
       成员 o.fn2 (?bo) = o.fn1 bo
    
       成员 o.fn3 (?bo) = 
       匹配博与
         |一些v-> 1 + bo.值
         |无 -> 1
    
       成员 o.fn4 (?bo) = o.fn3()
    

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

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

let plot(?x,?y,?color)

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

plot(data)
plot(y=data)
plot(x=data, color='r')

但不是:

plot(Some data)
plot(y=Some data)
plot(x=Some data, color=Some 'r')
  1. fn2 works because fn1 does not use its parameter, which is thus generic '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
    
  2. fn4 complains that the parameter passed to fn3 should be an int, but not int option because when you specify the parameter, you of course need to pass in a specific one. But you have the option to omit the parameter. The definition/type signature of fn3 does not know whether you have specify bo or not, so it is a int option. Notice that you may have the following usage:

    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()
    

where you don't specify the parameter for fn3, but when you specify it, it is a concrete int, not int option.

Think about a plotting function with three parameters:

let plot(?x,?y,?color)

because the parameters are optional, you can have the following usage:

plot(data)
plot(y=data)
plot(x=data, color='r')

But not:

plot(Some data)
plot(y=Some data)
plot(x=Some data, color=Some 'r')
终弃我 2024-11-22 15:09:28

F# 不需要匹配来传递可选参数。
使用绘图示例:

type Plotter() =
    static member Plot(?x,?y,?color) = 
        printfn $"{x}, {y}, {color}" // Do something "plottish" here

type PlotUser() =
    static member MyPlotUser(?x, ?y, ?color) =
        Plotter.Plot(?x = x, ?y = y, ?color = color)

/// Perform calls
PlotUser.MyPlotUser(10) // => Some(10), , 
PlotUser.MyPlotUser(10, color = "Green") // => Some(10), , Some(Green)

上面的示例允许您使用自己的可选参数调用绘图。
/JEE,夏普#Soft

F# does not require matching to pass optional arguments.
Using the plot-example:

type Plotter() =
    static member Plot(?x,?y,?color) = 
        printfn 
quot;{x}, {y}, {color}" // Do something "plottish" here

type PlotUser() =
    static member MyPlotUser(?x, ?y, ?color) =
        Plotter.Plot(?x = x, ?y = y, ?color = color)

/// Perform calls
PlotUser.MyPlotUser(10) // => Some(10), , 
PlotUser.MyPlotUser(10, color = "Green") // => Some(10), , Some(Green)

The above lets you call plot with your own optional arguments.
/JEE, Sharp#Soft

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文