2009-12-15 4 views
7

Mi sto appena avviando con F # e vediamo come è possibile utilizzare il currying per precaricare il 1 ° parametro a una funzione. Ma come si farebbe con il 2 °, 3 ° o qualunque altro parametro? Chiamerei i parametri per renderlo più facile? Esistono altri linguaggi funzionali che hanno chiamato parametri o un altro modo per rendere il curriculum indifferente all'ordine dei parametri?Come si curry il parametro 2nd (o 3rd, 4th, ...) in F # o in qualsiasi linguaggio funzionale?

+0

In Haskell c'è un 'funzione di flip' che inverte l'ordine di parametri di una funzione. Con quello puoi farlo sul secondo parametro. –

+0

E una combinazione di 'flip' e' (.) 'Ti permetterà di estenderlo a qualsiasi parametro. – ephemient

risposta

14

In genere è sufficiente utilizzare un lambda:

fun x y z -> f x y 42 

è una funzione come 'f', ma con il terzo parametro legato a 42.

È inoltre possibile utilizzare combinatori (come qualcuno ha detto "flip di Haskell "in un commento), che riordina gli argomenti, ma a volte lo trovo confuso.

Si noti che la maggior parte delle funzioni al curry vengono scritte in modo che l'argomento più probabile da applicare parzialmente venga prima.

F # ha i parametri con nome per i metodi (non i valori delle funzioni let-bound), ma i nomi si applicano ai parametri 'tupled'. I parametri al curry nominati non hanno molto senso; se ho una a due argomenti funzione curry 'f', mi sarei aspettato che, data

let g = f 
let h x y = f x y 

poi 'g' o 'h' sarebbe sostituibili per 'f', ma i parametri di 'nome' rendono questo non necessariamente vero. Vale a dire, i "parametri nominati" possono interagire male con altri aspetti del design del linguaggio e personalmente non conosco un buon design per "parametri nominati" che interagiscono bene con i "valori di funzione al curry di prima classe".

3

OCaml, la lingua su cui è basato F #, ha argomenti etichettati (e facoltativi) che possono essere specificati in qualsiasi ordine e che è possibile applicare parzialmente una funzione in base ai nomi di tali argomenti. Non credo che F # abbia questa caratteristica.

Si potrebbe provare a creare qualcosa come la funzione flip di Haskell. Creare varianti che saltino ulteriormente l'argomento nella lista degli argomenti non dovrebbe essere troppo difficile.

let flip f a b = f b a 
let flip2 f a b c = f b c a 
let flip3 f a b c d = f b c d a 
+0

F # ha argomenti denominati opzionali, ma sono solo per le definizioni 'member' (non per le definizioni' let'), e non possono essere curried in questo modo (tutti gli argomenti che non specifichi prendono i loro valori predefiniti, e non puoi ometti quelli non opzionali). –

+0

@Pavel: guarda la mia risposta. – ttsiodras

2

In Python, è possibile utilizzare functools.partial o una lambda. Python ha nominato argomenti. functools.partial può essere utilizzato per specificare i primi argomenti posizionali e qualsiasi argomento con nome.

from functools import partial 

def foo(a, b, bar=None): 
    ... 

f = partial(foo, bar='wzzz') # f(1, 2) ~ foo(1, 2, bar='wzzz') 
f2 = partial(foo, 3)   # f2(5) ~ foo(3, 5) 

f3 = lambda a: foo(a, 7)  # f3(9) ~ foo(9, 7) 
+0

La domanda non riguardava affatto Python. – Wes

+0

Il titolo della domanda dice: "... o qualsiasi linguaggio funzionale". – codeape

+4

Python non funziona, non importa quante persone provino e sostengano che sia – Wes

2

Solo per completezza - e dal momento che lei ha chiesto informazioni sugli altri linguaggi funzionali - come si farebbe in OCaml, probabilmente la "madre" di F #:

$ ocaml 
# let foo ~x ~y = x - y ;; 
val foo : x:int -> y:int -> int = <fun> 
# foo 5 3;; 
- : int = 2 
# let bar = foo ~y:3;; 
val bar : x:int -> int = <fun> 
# bar 5;; 
- : int = 2 

Quindi, in OCaml si può hardcode qualsiasi parametro chiamato che vuoi, semplicemente usando il suo nome (nell'esempio sopra).

Microsoft ha scelto di non implementare questa funzione, come hai scoperto ... A mio modesto parere, non si tratta di "scarsa interazione con altri aspetti del design del linguaggio" ... è più probabile a causa dello sforzo aggiuntivo ciò richiederebbe (nell'implementazione del linguaggio) e il ritardo che causerebbe nel portare la lingua nel mondo - quando in realtà solo poche persone (a) dovrebbero essere a conoscenza del "stepdown" da OCaml, (b) usano argomenti di funzione denominati Comunque.

io sono in minoranza, e li uso - ma è davvero qualcosa di facilmente emulato in F # con l'associazione di una funzione locale:

let foo x y = x - y 
let bar x = foo x 3 
bar ...