Используйте оператор list cons (a :: b) как функцию - PullRequest
17 голосов
/ 29 сентября 2010

F # позволяет вам превращать операторы в функции, окружая их ( ): например, (+) имеет тип int -> int -> int.

Возможно ли это сделать с помощью оператора list cons, ::?

Он не ведет себя как обычный бинарный оператор:

FSI> (::);;

  (::);;
  -^^

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

И метод List.Cons принимает кортеж; это не карри.

(Полезно сделать это. Например, вы можете использовать его для реализации карты в терминах сгиба ).

Ответы [ 3 ]

16 голосов
/ 29 сентября 2010

Перефразировано с http://cs.hubfs.net/forums/permalink/11713/11713/ShowThread.aspx#11713

(::) является «конструктором» различаемого объединения для list<'a> type, и поэтому возникает вопрос о том, должны ли его аргументы в качестве значения функции быть каррированными (как +) или кортежными (как все конструкторы DU). В любом случае некоторым людям кажется странным / неожиданным, поэтому F # просто запрещает конструкцию.

Конечно, вы всегда можете написать, например,

let cons x y = x :: y

и используйте cons, или просто используйте лямбду fun x y -> x::y, если вы хотите для этого «функцию префикса карри из двух аргументов».

6 голосов
/ 29 сентября 2010

К сожалению, нет, вы не можете. :: не оператор, а «символическое ключевое слово» в соответствии с грамматикой языка (см. Раздел 3.6 спецификации ), как и :?> и некоторые другие. Тем не менее, язык здесь не совсем согласован, поскольку есть несколько символических ключевых слов, которые можно рассматривать как операторы (по крайней мере (*) и (<@ @>)).

4 голосов
/ 29 сентября 2010

:: и [] могут быть представлены как List<_>.Cons и List<_>.Empty соответственно. Имейте в виду, что первый принимает в качестве аргумента кортеж. Это здесь, поэтому списки могут быть созданы на языках, отличных от 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:clo@24-7> //'

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