Использовать оператор списка 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).
Ответы
Ответ 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 = []