2010-09-29 5 views
16

F # lässt Sie Operatoren in Funktionen umwandeln, indem Sie sie mit ( umgeben: Beispiel: (+) ist vom Typ int -> int -> int.Verwenden Sie den Listen-Cons-Operator (a :: b) als Funktion

Ist es möglich, dies mit dem Listen-Cons-Operator :: zu tun?

Es verhält sich nicht wie ein normaler Binäroperators:

FSI> (::);; 

    (::);; 
    -^^ 

c:\temp\stdin(3,2): error FS0010: Unexpected symbol '::' in expression. 
Expected ')' or other token. 

Und die List.Cons Methode nimmt ein Tupel; es ist nicht curried.

(Es ist nützlich, dies zu tun. Zum Beispiel können Sie es verwenden, um map in terms of fold zu implementieren).

+0

Kannst du nicht einfach einen kleinen Wrapper um '' 'oder' List.Cons' schreiben? – leppie

+0

Ookay, das ist wirklich komisch. Du kannst einfach 'fun x y -> x :: y' gehen, aber ich habe keine Ahnung, warum es so eine sinnlose Inkonsistenz gibt - Vielleicht, weil' :: 'in Musteranpassungen verwendet werden kann und speziell behandelt wird? Aber das wäre immer noch kein Grund. – Dario

+0

Interessante Frage. Das funktioniert für concat '(@)' gedacht. – Stringer

Antwort

16

Umschrieben von http://cs.hubfs.net/forums/permalink/11713/11713/ShowThread.aspx#11713

(::) ist eine diskriminiert Vereinigung ‚Konstruktor‘ für die list<'a> type und erhöht so die Frage, ob als Funktionswert sollte seine Argumente curried (wie +) oder fach vervielfachten werden (wie alle DU-Konstruktoren). In jedem Fall scheint es für manche Leute fischig/unerwartet zu sein, so dass F # das Konstrukt einfach nicht erlaubt.

Natürlich können Sie immer z.

let cons x y = x :: y 

und verwenden cons, oder verwenden Sie nur einen Lambda-fun x y -> x::y, wenn Sie eine „curried Präfix Funktion von zwei args“ für diese wollen.

6

Leider nein, das geht nicht. :: ist kein Operator, sondern ein "symbolisches Schlüsselwort" entsprechend der Sprachgrammatik (siehe Abschnitt 3.6 of the spec), ebenso wie :?> und einige andere. Die Sprache scheint hier jedoch nicht vollständig konsistent zu sein, da es einige symbolische Schlüsselwörter gibt, die so behandelt werden können, als wären sie Operatoren (mindestens (*) und (<@ @>)).

4

:: und [] können beide durch List<_>.Cons bzw. List<_>.Empty dargestellt werden. Bedenken Sie jedoch, dass Ersteres ein Tupel als Argument verwendet. Diese sind hier, damit Listen in anderen Sprachen als F # erstellt werden können.

> List.Cons(4, List.Empty);; 
val it : int list = [4] 

> 4::[];; 
val it : int list = [4] 

> List<int>.Cons(4, List<int>.Empty);; 
val it : int list = [4] 

> List.Cons;; 
val it : 'a * 'a list -> 'a list = <fun:[email protected]> //' 

> List<int>.Empty;; 
val it : int list = [] 
+0

Danke. Ich hatte eine prolbem konvertieren ML op :: zu F # wo (Spaß x y -> x :: y) konnte nicht kompilieren, aber Liste <_> .Cons funktioniert. –