2009-11-30 4 views
8

vorbei Können Sie „von 2 divide“ in einer Operation wie Pass oder „subtrahieren 1“ mit nur einem teilweise angelegten Operator, wobei „1 add“ sieht wie folgt aus:Fis einen Operator mit Argumenten an eine Funktion

List.map ((+) 1) [1..5];; //equals [2..6] 
// instead of having to write: List.map (fun x-> x+1) [1..5] 

Was passiert ist, wird 1 als erstes Argument auf (+) angewendet, und das Listenelement wird als zweites Argument angewendet. Für Addition und Multiplikation spielt diese Reihenfolge der Argumente keine Rolle.

Angenommen, ich möchte 1 von jedem Element subtrahieren (dies wird wahrscheinlich eine gemeinsame Anfänger Fehler):

List.map ((-) 1) [1..5];; //equals [0 .. -4], the opposite of what we wanted 

1 wird an den (-) als erstes Argument, so dass anstelle von (list_item - 1), I erhalten (1 - list_item). Ich kann es umschreiben als Zugabe negativ statt Subtraktion positiv:

List.map ((+) -1) [1..5];; 
List.map (fun x -> x-1) [1..5];; // this works too 

Ich bin für einen ausdrucksvollen Weg, um es zu schreiben, so etwas wie ((-) _ 1), wo _ einen Platzhalter bezeichnet, wie in der Arc Sprache. Das würde 1 das zweite Argument zu - sein, also in List.map würde es list_item - 1 auswerten. Also, wenn Sie divide by 2 in die Liste Karte wollten, könnten Sie schreiben:

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 

dies getan werden kann oder muss ich (fun x -> x/2) benutzen? Es scheint, dass wir der Platzhaltersyntax am nächsten kommen, wenn wir ein Lambda mit einem benannten Argument verwenden.

Antwort

11

Sie könnten eine Flip-Funktion, so etwas wie schreiben:

let flip f x y = f y x 

List.map (flip (-) 1) [2;4;6] 

ich die Syntax falsch kann ich in F # nicht sehr fließend bin.

+8

Ihre Flip-Funktion kann (genauso gut) als 'let flip f x y = f y x' definiert werden –

+0

Das ist ein guter Kandidat für das Inlining. –

8

In F #, a la Haskell, und Platzhalterargumenten gibt es keine 'Operationsabschnitte' (anscheinend ein Arc). Sie können einen 'Flip'-Kombinator verwenden, wie in einer anderen Antwort vorgeschlagen, um die Reihenfolge der Argumente umzukehren und dann das erste (jetzt zweite) Argument teilweise anzuwenden.

Aber ich würde nur

fun x -> x/2 

verwenden, wenn Sie Code-Golf spielen, glaube ich nicht, noch ein paar Zeichen zu rasieren versuchen, weg alles, was man hier kauft.

8

Die flip ige Lösung von Logan Capaldo vorgeschlagen können auch einen Operator geschrieben werden (hier >.):

let (>.) x f = (fun y -> f y x) 
List.map (1 >. (-)) [2;4;6] 

Oder wenn Sie es vorziehen, die Operanden umgekehrt:

let (>.) f x = (fun y -> f y x) 
List.map ((-) >. 1) [2;4;6] 

bearbeiten : Mit einem Operator, der "eher wie ein Platzhalter aussieht" (hier >-<), kommen Sie Ihrer vorgeschlagenen Syntax sehr nahe:

'_' ist leider (?) Nicht a valid operator symbol in F#.

+1

:) Smiley. :(frownie.: p Zunge.> - . Ein Auge stocherte aus. (Stirnrunzeln mit einem Auge stocherte aus. – Juliet

Verwandte Themen