Come si esegue questo haskell in F # in modo pulito?F # versione di corrispondenza del modello haskell
add 1 2 x = 3 + x
add 1 x y = 1 + x + y
add z x y = z + x + y
Come si esegue questo haskell in F # in modo pulito?F # versione di corrispondenza del modello haskell
add 1 2 x = 3 + x
add 1 x y = 1 + x + y
add z x y = z + x + y
Non si può sovraccaricare la funzione stessa, ma è possibile utilizzare il pattern matching direttamente:
let add z x y = // curried multiple parameters
match z, x, y with // convert to three-tuple to match on
| 1, 2, x -> 3 + x
| 1, x, y -> 1 + x + y
| z, x, y -> z + x + y
Usage è come previsto: add 1 2 3
Se siete disposti a usare tuple come argomenti (vale a dire rinunciare al curriculum e applicazione parziale), si può anche scrivere in modo più stenografico:
let add = // expect three-tuple as first (and only) parameter
function // use that one value directly to match on
| 1, 2, x -> 3 + x
| 1, x, y -> 1 + x + y
| z, x, y -> z + x + y
Usage ora è: add (1, 2, 3)
Grazie! Cercavo gli esempi di corrispondenza del modello f # dappertutto e nessuno corrispondeva a più di un parametro nei campioni, mi è stato dato l'impressione che non si potesse fare questo. –
@Jimmy: Tecnicamente una singola tupla viene abbinata qui, quindi non hai sbagliato ... – ildjarn
@ildjarn: solo nel secondo esempio che non è quello che userei perché si perde il currying/applicazione parziale che ritengo sia una delle parti più vantaggiose di queste lingue –
Ricordiamo in Haskell che il general form of functions come una lista di dichiarazioni con i modelli:
f pat1 ... = e1
f pat2 ... = e2
f pat3 ... = e3
è solo zucchero per l'analisi case
:
f x1 .. xn = case (x1, .. xn) of
(pat1, ..., patn) -> e1
(pat2, ..., patn) -> e2
(pat3, ..., patn) -> e3
così la stessa traduzione può essere fatta ad altre lingue con pattern matching ma senza pattern a livello di dichiarazione.
Mi rendo conto che è solo un caso, ma il motivo per cui lo zucchero esiste in haskell è per la pulizia, speravo che qualcosa di simile esistesse in f #, e come ha sottolineato yamen, la corrispondenza in f # può funzionare allo stesso modo –
Questo è puramente sintattico. Linguaggi come Haskell, Standard ML e Mathematica consentono di scrivere fuori diversi casi partita come se fossero diverse funzioni:
factorial 0 = 1
factorial 1 = 1
factorial n = n * factorial(n-1)
mentre linguaggi come OCaml e F # richiedono di avere una sola definizione di funzione e utilizzare match
o equivalente in il suo corpo:
let factorial = function
| 0 -> 1
| 1 -> 1
| n -> n * factorial(n-1)
si noti che non c'è bisogno di copiare il nome della funzione più e più volte con questa sintassi e si può scomporre i casi di corrispondenza più facilmente:
let factorial = function
| 0 | 1 -> 1
| n -> n * factorial(n-1)
Come scrisse Yamen, fare curriculum con let f a b = match a, b with ...
in F #.
Nel classico implementazione albero rosso-nero, trovo la duplicazione dei nomi delle funzioni e poi sul lato destro in standard ML e Haskell abbastanza brutto:
balance :: RB a -> a -> RB a -> RB a
balance (T R a x b) y (T R c z d) = T R (T B a x b) y (T B c z d)
balance (T R (T R a x b) y c) z d = T R (T B a x b) y (T B c z d)
balance (T R a x (T R b y c)) z d = T R (T B a x b) y (T B c z d)
balance a x (T R b y (T R c z d)) = T R (T B a x b) y (T B c z d)
balance a x (T R (T R b y c) z d) = T R (T B a x b) y (T B c z d)
balance a x b = T B a x b
rispetto all'equivalente OCaml o F #:
let balance = function
| B, z, (T(R, y, T(R, x, a, b), c) | T(R, x, a, T(R, y, b, c))), d
| B, x, a, (T(R, z, T(R, y, b, c), d) | T(R, y, b, T(R, z, c, d))) ->
T(R, y, T(B, x, a, b), T(B, z, c, d))
| a, b, c, d -> T(a, b, c, d)
Non so haskell, qual è l'obiettivo qui? Sembra un'ottimizzazione che il compilatore catturerebbe e risolverebbe. Penso che cercare di scrivere un equivalente in F # con la corrispondenza dei pattern sia più lento. Cosa stai cercando di ottenere? – gjvdkamp
gjvdkamp, non è un ottimizzazione, è un dispositivo sintattico che rende ogni caso più facile da leggere. 'f 1 = x; f 2 = y' è tradotto in 'f a = caso a di 1 -> x; 2 -> y' - http://www.haskell.org/onlinereport/decls.html#sect4.4.3.1 –