Potete passare in un'operazione come "dividere per 2" o "sottrarre 1" utilizzando solo un operatore parzialmente applicata, dove "aggiungere 1" si presenta così:F # passando un operatore con gli argomenti a una funzione
List.map ((+) 1) [1..5];; //equals [2..6]
// instead of having to write: List.map (fun x-> x+1) [1..5]
Quello che sta succedendo è che 1 viene applicato a (+) come primo argomento e l'elemento della lista viene applicato come secondo argomento. Per addizione e moltiplicazione, questo ordinamento di argomenti non ha importanza.
Supponiamo che voglio sottrarre 1 da ogni elemento (questo sarà probabilmente un principiante errore comune):
List.map ((-) 1) [1..5];; //equals [0 .. -4], the opposite of what we wanted
1 viene applicato alla (-) come primo argomento, così invece di (list_item - 1)
, I ottenere (1 - list_item)
. Posso riscriverlo come l'aggiunta di uno negativo invece di sottrarre positiva:
List.map ((+) -1) [1..5];;
List.map (fun x -> x-1) [1..5];; // this works too
Sto cercando un modo più espressivo di scriverlo, qualcosa come ((-) _ 1)
, dove _
indica un segnaposto, come nella lingua Arc. Ciò farebbe sì che 1
diventi il secondo argomento a -
, quindi in List.map verrà valutato su list_item - 1
. Quindi, se si voleva mappare divide by 2
alla lista, si potrebbe scrivere:
List.map ((/) _ 2) [2;4;6] //not real syntax, but would equal [1;2;3]
List.map (fun x -> x/2) [2;4;6] //real syntax equivalent of the above
si può fare o devo usare (fun x -> x/2)
? Sembra che la cosa più vicina alla sintassi del segnaposto sia quella di usare un lambda con un argomento con nome.
La funzione flip può essere definita come "flip f x y = f y x" –
Questo è un buon candidato per l'inlining. –