2010-09-29 15 views
16

F # umożliwia przekształcenie operatorów w funkcje poprzez otaczanie ich za pomocą (): na przykład (+) jest typu int -> int -> int.Użyj operatora listy (a :: b) jako funkcji

Czy można to zrobić z listą operatorów kos, ::?

on nie zachowuje się jak normalny operatorem binarnym:

FSI> (::);; 

    (::);; 
    -^^ 

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

i sposobu List.Cons trwa krotki; to nie jest curry.

(Przydaje się to zrobić, na przykład można go użyć do implementacji map in terms of fold).

+0

Nie możesz po prostu napisać małego opakowania wokół '::' lub 'List.Cons'? – leppie

+0

Ookay, to naprawdę dziwne. Możesz po prostu przejść "fun x y -> x :: y", ale nie mam pojęcia, dlaczego istnieje taka bezmyślna niespójność - może dlatego, że '::' może być używane w dopasowaniach wzorców i traktowane jest jako specjalne? Ale nadal nie ma powodu. – Dario

+0

Interesujące pytanie. Działa to dla myśli concat '(@)'. – Stringer

Odpowiedz

16

sparafrazować z http://cs.hubfs.net/forums/permalink/11713/11713/ShowThread.aspx#11713

(::) jest dyskryminowany union „konstruktor” dla list<'a> type i tak postawił pytanie, czy jako wartość funkcji argumenty należy curry (jak +) lub tupled (jak wszystkie konstruktory DU). Tak czy inaczej, niektórzy ludzie wydają się podejrzani/nieoczekiwani, więc F # po prostu uniemożliwia konstrukt.

Oczywiście zawsze możesz napisać np.

let cons x y = x :: y 

i używać cons, lub po prostu użyć lambda fun x y -> x::y, jeśli chcesz „curry funkcji prefiksu dwoma argumentami” za to.

6

Niestety, nie, nie możesz. :: nie jest operatorem, ale "słowem symbolicznym" zgodnie z gramatyką języka (zob. Sekcja 3.6 of the spec), podobnie jak :?> i kilkoma innymi. Język nie wydaje się tu jednak całkowicie spójny, ponieważ istnieje kilka symbolicznych słów kluczowych, które można traktować tak, jakby były operatorami (co najmniej (*) i (<@ @>)).

4

:: i [] mogą być reprezentowane odpowiednio przez List<_>.Cons i List<_>.Empty. Pamiętaj jednak, że ten pierwszy bierze krotkę jako argument. Są tutaj, więc listy mogą być tworzone w językach innych niż F #.

> 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

Dzięki. Miałem prolbem przekonwertować ML op :: na F #, gdzie (zabawa x y -> x :: y) nie udało się skompilować, ale lista <_>. Con pracowała. –

Powiązane problemy