2012-04-26 24 views
5

我想实现一个可以接受1或2个参数的F#函数。我想用这样的功能:如何在F#中实现可变参数

let foo = ... 
foo "a" 
foo "a" "b" 

这两个参数可以是相同的类型。我读了约匹配模式,有效模式的页面,但找不到一个适合我的作品。

+0

这是一个不好的习惯来回答,你并不需要它,但这就是我想到的。如果你的参数是一个相同类型的值的列表,就把它们作为一个“列表”。如果其中一个是可选的(例如可能有可省略的默认值),则可选:'foo(a,?b)'。如果你的数据可以用这种方式表示,你也可以考虑DU。否则,我只会使用两个函数。 – bytebuster 2012-04-26 19:33:58

回答

2

除了其他答案之外,您也可以通过部分应用和currying来做你想做的事情。像这样:

let foo a b = 
    a + b 

let foo2 a = 
    foo 1 a;; 

很明显,您想要将foo2中的foo调用中的第一个参数修复为您想要的任何默认值。

7

我相信这是由于一些潜在的.NET功能,但我认为你必须使用具有重载方法的类 - 像

type t() = 
    static member foo a = "one arg" 
    static member foo (a,b) = "two args" 
+5

请注意,第二个必须是一个元组,否则在调用第一个重载和第二个重载之间'foo“a”'是不明确的。 – Guvante 2012-04-26 16:22:02

5

的东西。一类会员,您可以使用可选的PARAMS :

type Helper private() = 
    static member foo (input1, ?input2) = 
      let input2 = defaultArg input2 "b" 
      input1, input2 

要调用这个方法:

Helper.foo("a") 
Helper.foo("a", "b") 

这是你以后在做什么?

不幸的是,你不能在函数上使用可选参数。

3

除了其他答案,这里还有几个“几乎解决方案”。它们并不完全是你想要的,但无论如何都值得了解。

使用列表(或阵列)和模式匹配:

let f = function 
    | [a, b] -> ... 
    | [a] -> ... 
    | [] -> failwith "too few arguments" 
    | _ -> failwith "too many arguments" 

f ["a"] 
f ["a" ; "b"] 

问题:参数没有被命名,而不是从函数签名有多少参数需要明确。

使用记录来传递所有可选参数:

type FParams = { a : string; b : string } 
let fdefault = { a = "a" ; b = "b" } 

let f (pars: FParams) = ... 

f { fdefault with b = "c" } 

问题:一个也是可选的,这是不是你想要的。虽然可以有用。