Подтвердить что ты не робот

Использовать оператор списка cons (a:: b) как функцию

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

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

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

FSI> (::);;

  (::);;
  -^^

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

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

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

4b9b3361

Ответ 1

Парафраз из http://cs.hubfs.net/forums/permalink/11713/11713/ShowThread.aspx#11713

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

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

let cons x y = x :: y

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

Ответ 2

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

Ответ 3

:: и [] могут быть представлены как 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:[email protected]> //'

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