2012-04-26 15 views
5

Chcę zaimplementować funkcję F #, która może przyjąć 1 lub 2 argumenty. Chciałbym użyć funkcji podobnej do tej:Jak implementować zmienne argumenty w F #

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

Oba argumenty mogą być tego samego typu. Przeczytałem strony o wzorze zapałek, aktywny wzór, ale nie mogę znaleźć jednego działa dla mnie.

+0

To zły nawyk, aby odpowiedzieć, tak naprawdę nie potrzebujesz go, ale to przychodzi mi do głowy. Jeśli twoje argumenty są listą wartości tego samego typu, po prostu ustaw je jako "listę". Jeśli jeden z nich jest opcjonalny (np. Może mieć wartość domyślną, którą można pominąć), dodaj opcjonalny: 'foo (a,? B)'. Możesz także rozważyć DU, jeśli twoje dane mogą być reprezentowane w ten sposób. W przeciwnym razie użyłbym tylko dwóch funkcji. – bytebuster

Odpowiedz

2

Oprócz innych odpowiedzi, możesz również być w stanie robić, co chcesz, poprzez częściową aplikację i curry. W ten sposób:

let foo a b = 
    a + b 

let foo2 a = 
    foo 1 a;; 

Oczywiście należy poprawić pierwszy parametr w wywołaniu foo w foo2 na dowolną wartość domyślną.

7

Wierzę, że to ze względu na niektóre z podstawowych funkcji .NET, ale myślę, że trzeba korzystać z metod klasy przeciążenia - coś podobnego

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

Zauważ, że druga musi być krotką, ponieważ inaczej 'foo" a "' jest niejednoznaczne między wywołaniem pierwszego przeciążenia a wygaśnięciem drugiego. – Guvante

5

na elemencie typu, można użyć opcjonalnych params :

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

Aby wywołać tę metodę:

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

Czy to ty jesteś po?

Niestety, nie można użyć opcjonalnych parametrów dla funkcji.

3

Oprócz innych odpowiedzi, oto kilka "prawie rozwiązań". Nie są one dokładnie tym, czego chcieli, ale i tak warto je poznać.

Korzystanie z listy (lub tablicę) i dopasowanie Wzór:

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

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

problemów: parametry nie są nazwane, nie wynika z funkcji podpisu ile parametry trzeba.

Używanie rekordu przejść wszystkie parametry opcjonalne:

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

let f (pars: FParams) = ... 

f { fdefault with b = "c" } 

Problem: a jest też opcja, która nie jest to, czego chciał. Może być jednak użyteczny.