20

F# 允许您通过用 : 包围运算符将它们转换为函数,( )例如(+)is 类型int -> int -> int

是否可以使用 list cons 运算符来做到这一点::

它的行为不像普通的二元运算符:

FSI> (::);;

  (::);;
  -^^

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

List.Cons方法采用一个元组;它不是咖喱。

(能够做到这一点很有用。例如,您可以使用它来实现map 方面的 fold)。

4

3 回答 3

17

转述自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,如果你想要一个“两个参数的咖喱前缀函数”。

于 2010-09-29T17:08:15.377 回答
6

不幸的是,不,你不能。 ::不是运算符,而是根据语言语法(参见规范的第 3.6节)的“符号关键字”,:?>和其他一些一样。但是,这里的语言似乎并不完全一致,因为有一些符号关键字可以被视为运算符(至少是(*)and (<@ @>))。

于 2010-09-29T12:38:04.883 回答
4

::并且[]都可以分别由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 = []
于 2010-09-29T16:28:22.190 回答