2012-04-26 15 views
5

Ich möchte eine F # -Funktion implementieren, die 1 oder 2 Argumente akzeptieren kann. Ich möchte die Funktion wie folgt verwenden:So implementieren Sie variable Argumente in F #

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

Beide Argumente können vom gleichen Typ sein. Ich lese die Seiten über Spielmuster, aktive Muster, kann aber nicht finden, funktioniert für mich.

+0

Es ist eine schlechte Angewohnheit zu antworten, Sie brauchen es nicht wirklich, aber das kommt mir in den Sinn. Wenn Ihre Argumente eine Liste von Werten desselben Typs sind, machen Sie sie einfach zu einer 'Liste'. Wenn einer von ihnen optional ist (z. B. kann er einen Standardwert haben, der weggelassen werden kann), mach es optional: 'foo (a,? B)'. Sie können auch DU in Betracht ziehen, wenn Ihre Daten auf diese Weise dargestellt werden können. Ansonsten würde ich nur zwei Funktionen verwenden. – bytebuster

Antwort

2

Zusätzlich zu den anderen Antworten können Sie möglicherweise auch tun, was Sie wollen, durch partielle Anwendung und Curry. Wie folgt aus:

let foo a b = 
    a + b 

let foo2 a = 
    foo 1 a;; 

Offensichtlich würden Sie den ersten Parameter im Aufruf beheben innerhalb foo2 foo, was auch immer Standard Sie wollen.

7

Ich glaube, das einige der zugrunde liegenden .NET Features zurückzuführen ist, aber ich glaube, Sie haben eine Klasse mit überladenen Methoden verwenden - so etwas wie

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

Beachten Sie, dass es sich bei der Sekunde um ein Tupel handeln muss, da andernfalls "foo" a "' zwischen dem Aufrufen der ersten Überladung und dem Currieren der zweiten nicht eindeutig ist. – Guvante

5

Auf einem Typ-Mitglied können Sie optional params verwenden :

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

diese Methode zu nennen:

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

Ist das, was nach der du bist?

Sie können leider keine optionalen Parameter für eine Funktion verwenden.

3

Zusätzlich zu den anderen Antworten, hier sind ein paar mehr "fast Lösungen". Sie sind nicht genau das, was du wolltest, aber sie sind trotzdem wissenswert.

Mit einer Liste (oder ein Array) und Pattern-Matching:

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

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

Probleme: Parameter nicht genannt werden, nicht klar von Funktionssignatur, wie viele Parameter es dauert.

einen Datensatz Mit allen optionalen Parameter zu übergeben:

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

let f (pars: FParams) = ... 

f { fdefault with b = "c" } 

Problem: a ist ebenfalls optional, das ist nicht, was Sie ist wollte. Kann aber nützlich sein.