2010-05-08 14 views
6

Es ist kein praktisch wichtiges Problem, aber ich würde gerne ein Beispiel von tacit programming in F # sehen, wo meine point-free Funktionen mehrere Argumente haben können (nicht in Form einer Liste oder Tupel) .Impliziter Programmierstil mit F #

Und zweitens, wie solche Funktionen eine komplexe Datenstruktur manipulieren können. Ich probiere es in F # Interactive aus, habe aber noch keinen Erfolg.

Ich habe versucht, zum Beispiel:

> (fun _ -> (fun _ -> (+))) 333 222 111 555 

Ist das richtig?

Und:

> (fun _ -> (fun _ -> (+))) "a" "b" "c" "d";; 

val it : string = "cd" 
+3

Sie sollten "point-free" anstelle von "sinnlos" verwenden. Es ist der Standardbegriff. :) –

Antwort

4

F # nicht einige der grundlegenden Funktionen enthalten, die in Haskell verfügbar sind (vor allem, weil F # Programmierer in der Regel die explizite Art der Programmierung bevorzugen und pointfree Stil nur in den offensichtlichsten Fällen verwenden , wo es Lesbarkeit nicht schadet).

auch immer Sie ein paar grundlegende combinators wie folgt definieren:

// turns curried function into non-curried function and back 
let curry f (a, b) = f a b 
let uncurry f a b = f (a, b) 

// applies the function to the first/second element of a tuple 
let first f (a, b) = (f a, b) 
let second f (a, b) = (a, f b) 

Jetzt können Sie die Funktion implementieren können Längen von zwei Strings mit combinators hinzufügen wie folgt:

let addLengths = 
    uncurry (((first String.length) >> (second String.length)) >> (curry (+))) 

Diese Konstrukte zwei Funktionen Diese wendet String.length auf das erste/zweite Element eines Tupels an, setzt sie dann zusammen und fügt dann die Elemente des Tupels unter Verwendung von + hinzu. Die ganze Sache ist in uncurry verpackt, so erhalten Sie eine Funktion des Typs string -> string -> int.

+0

Ich habe das in FSI überprüft und es funktioniert! Vielen Dank; Übrigens, könnten Sie erklären, wie Sie zu dieser Tupel-Funktion-Kompositionssyntax gelangt sind? Ich meine '(first String.length) >> (second String.length)' Sieht für mich etwas ungewöhnlich aus;) – Bubba88

+0

Das erreicht man mit der Funktionszusammenstellung '>>'. Zum Beispiel bedeutet "f >> g", dass für ein Argument "x" 'g (f (x))' heißt. Im obigen Fall verwandelt die erste Funktion ('first String.length') eine Tupel' string * string' in ein Tupel 'int * string' und die zweite Funktion (' second String.length') verwandelt diese in 'int *. int 'enthält die Längen. –

+0

Sie implementieren praktisch Pfeile für F #;) Okay, warum nicht - Pfeile wurden als eine Kombination aus Monaden und stillschweigender Programmierung erfunden. – Dario

2

In F # ist die arity von Funktionen festgelegt, so dass Sie nicht beide schreiben

(op) 1 2 

und

(op) 1 2 3 4 

op für einen bestimmten Betreiber gehen zu können. Sie müssen eine Liste oder andere Datenstruktur verwenden, wenn Sie das möchten. Wenn Sie nur benannte Variablen vermeiden möchten, können Sie immer "1 + 2 + 3 + 4" verwenden. Die idiomatische Methode zum Hinzufügen einer Liste von Zahlen in F # ist List.sum [1;2;3;4], die auch Variablen vermeidet.