2012-04-26 6 views
5

Quiero implementar una función F # que puede aceptar 1 o 2 argumentos. Me gustaría utilizar la función de esta manera:Cómo implementar argumentos variables en F #

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

Ambos argumentos pueden ser del mismo tipo. Leí las páginas sobre coinciden patrón, patrón activo, pero no puedo encontrar uno funciona para mí.

+0

Es un mal hábito responder, realmente no lo necesitas, pero eso es lo que se me viene a la mente. Si tus argumentos son una lista de valores del mismo tipo, simplemente hazlos una 'lista'. Si uno de ellos es opcional (por ejemplo, puede tener un valor predeterminado que se puede omitir), hágalo opcional: 'foo (a,? B)'. También puede considerar DU, si sus datos pueden ser representados de esta manera. De lo contrario, solo usaría dos funciones. – bytebuster

Respuesta

2

Además de las otras respuestas, también puede hacer lo que quiera a través de la aplicación parcial y el currying. De esta manera:

let foo a b = 
    a + b 

let foo2 a = 
    foo 1 a;; 

Obviamente Lo que quiere fijar el primer parámetro en la llamada a foo dentro foo2 a lo predeterminado que desee.

7

Creo que esto es debido a algunas de las características de .NET subyacentes, pero yo creo que hay que utilizar una clase con métodos sobrecargados - algo así como

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

Tenga en cuenta que el segundo tiene que ser una tupla porque de lo contrario 'foo" a "' es ambiguo entre llamar a la primera sobrecarga y curr al segundo. – Guvante

5

En un miembro de tipo, puede utilizar parametros opcionales :

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

Para llamar a este método:

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

¿es esto lo que está buscando?

Desafortunadamente, no puede usar params opcionales en una función.

3

Además de las otras respuestas, aquí hay algunas más "casi soluciones". No son estrictamente lo que querías, pero vale la pena saber de todos modos.

El uso de una lista (o una matriz) y la coincidencia de patrones:

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

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

problemas: los parámetros no son nombrados, no está claro a partir de la firma función de cuántos parámetros que se necesita.

El uso de un registro de pasar todos los parámetros opcionales:

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

let f (pars: FParams) = ... 

f { fdefault with b = "c" } 

Problema: A es también opcional, que no es lo que quería. Puede ser útil sin embargo.

Cuestiones relacionadas