我正在阅读F#教程,并遇到了一个我不理解的语法示例。我正在阅读的页面链接位于底部。以下是该页面的示例:
let rec quicksort2 = function
| [] -> []
| first::rest ->
let smaller,larger = List.partition ((>=) first) rest
List.concat [quicksort2 smaller; [first]; quicksort2 larger]
// test code
printfn "%A" (quicksort2 [1;5;23;18;9;1;3])
我不明白的部分是:((>=) first)
。究竟是什么?相比之下,这是来自List.partition
的{{3}}的示例:
let list1 = [ 1 .. 10 ]
let listEven, listOdd = List.partition (fun elem -> elem % 2 = 0) list1
printfn "Evens: %A\nOdds: %A" listEven listOdd
List.partition
的第一个参数(这是正确的术语吗?)显然是一个匿名函数。我重写了这条线:
let smaller,larger = List.partition (fun e -> first >= e) rest
,它的工作原理与上面的例子相同。我只是不明白这个结构如何完成同样的事情:((>=) first)
答案 0 :(得分:5)
这与中缀符号与前缀符号大致相同 运算符也是函数,遵循相同的规则(即可以部分应用它们)
所以这里(>=) first
是运算符> = first
已经应用为“第一”操作数,并且在重写该行时注意到了一个等待运算符的第二个操作数的函数
答案 1 :(得分:3)
此构造结合了两个功能:带前缀表示的操作符调用和部分功能应用程序。
首先,让我们看看使用前缀表示法调用运算符。
let x = a + b
上面的代码使用两个参数+
和a
调用运算符b
。由于这是一种函数式语言,因此一切都是函数,包括运算符,包括运算符+
。这只是运算符有这个有趣的调用语法,你将函数放在之间而不是在它们之前。但你仍然可以像操作任何其他常规函数一样对待操作符。为此,您需要将其括在括号中:
let x = (+) a b // same thing as a + b.
当我说“和其他任何功能一样”时,我完全是这样说的:
let f = (+)
let x = f a b // still same thing.
接下来,让我们看一下部分功能应用。考虑这个功能:
let f x y = x + y
我们可以打电话给他并获得一个号码作为回报:
let a = f 5 6 // a = 11
但我们也可以通过仅提供两个参数中的一个来“几乎”调用它:
let a = f 5 // a is a function
let b = a 6 // b = 11
这种“几乎调用”(技术上称为“部分应用程序”)的结果是另一个仍然需要剩余参数的函数。
现在,让我们结合两个:
let a = (+) 5 // a is a function
let b = a 6 // b = 11
一般来说,可以写出以下等价物:
(+) x === fun y -> x + y
或者,类似地,对于您的具体情况:
(>=) first === fun y -> first >= y