为什么带有curried参数的f#函数不能有可选参数

时间:2015-12-31 18:49:29

标签: f#

好的我对F#很新,所以也许这在教科书中得到了很好的解释,但为什么带有curried参数的F#函数不能有可选参数。例如,函数Fun1不编译,而其他两个函数编译正常。我想知道对可选参数进行约束的原因是什么?是否存在解决此约束的方法?

type TestOptionalParameter = 
    member x.Fun1 (a: int) (?b : bool) = 
        if defaultArg b true then a else 2 * a
    member x.Fun2 (?b : bool) = 
        if defaultArg b true then "yes" else "no"
    member x.Fun3 (a: int, ?b : bool) = 
        if defaultArg b true then a else 2 * a

2 个答案:

答案 0 :(得分:3)

如果允许的话,让我们看一个例子:

let top = TestOptionalParameter()
let fn1 = top.Fun1 4

在这种情况下,类型fn1的{​​{1}}:功能的价值或方法Fun1调用的结果的默认值为2参数值((bool -> int))?

我认为由于这种歧义,带有curried参数的函数不允许有可选参数

答案 1 :(得分:2)

我想这是F#中的设计决策,因为OCaml中的curried函数中可以有可选参数。

F#中的可选参数是通过选项类型实现的,假设您具有(例如)int -> bool option -> int的函数,即使您对可选参数版本有一些特殊注释,例如: int -> ?bool -> int我认为在实际使用中理解这些函数的行为可能会变得更加困难,尤其是在存在部分应用程序的情况下,因为参数的数量并不总是与类型签名所暗示的相匹配。

对于您在OCaml中实施的此方法的一些缺点,您可能会对此答案感兴趣:https://stackoverflow.com/a/23703761/5438433

有人建议在F#语言设计用户语音网站的let绑定函数中实现可选参数:https://fslang.uservoice.com/forums/245727-f-language/suggestions/5663215-optional-and-named-parameters-on-let-bindings-on-m,我不清楚,如果接受,这将实现相同的行为目前可用于类型的可选参数或实现curried参数的类似OCaml的行为。