我需要使用几种方法来实现快速排序以选择数据透视表,因此我实现了一个将数据透视选择器作为参数的例程。但是具体实现的定义包含许多样板,是否有更简洁的方法来定义它们?
private def qsort[a <% Ordered[a]](xs: Stream[a])(choosePivot:Stream[a] => a): Stream[a] = {
if(xs.lengthCompare(1) <= 0) xs
else {
val pivot = choosePivot(xs)
val l = xs.filter(_ < pivot)
val r = xs.filter(_ > pivot)
qsort(l)(choosePivot) ++ pivot#::qsort(r)(choosePivot)
}
}
def qsortHead[a <% Ordered[a]](xs: Stream[a]) = qsort(xs)(ys => ys.head)
def qsortLast[a <% Ordered[a]](xs: Stream[a]) = qsort(xs)(ys => ys.last)
def qsortRandom[a <% Ordered[a]](xs: Stream[a]) = qsort(xs)(ys => ys(rng.nextInt(ys.length)))
在Haskell中,如果选择pivot函数是第一个参数,我可以写qsortHead = qsort head
之类的东西,如果是第二个参数,我可以写qsortHead xs = qsort xs (\ys -> head ys)
。 Scala中有类似的内容吗?
答案 0 :(得分:1)
对于使用传递参数的lambda表达式,下划线语法是你的朋友:_.head
qsort(xs)(_.head)
_.head
将被翻译为完整的表达式x => x.head
答案 1 :(得分:0)
我想指出Ordered
主要是从Scala标准库中逐步淘汰,而不是更为通用Ordering
。除非你有充分的理由使用我不了解的前者,否则后者可能是更好的选择。
它可能没有那么好,但如果你至少使用Ordering
,你可以摆脱丑陋的<%
运营商。我还建议使用@maasg建议的相同lambda速记(注意你不能将它用于更复杂的Random lambda):
def qsortHead[A: Ordering](xs: Stream[A]) = qsort(xs)(_.head)
def qsortLast[A: Ordering](xs: Stream[A]) = qsort(xs)(_.last)
def qsortRandom[A: Ordering](xs: Stream[A]) = qsort(xs)(ys => ys(rng.nextInt(ys.length)))
如果您想了解有关视图限制Ordered
和上下文绑定Ordering
之间差异的更多信息,请查看此问题:What are Scala context and view bounds?
由于Scala处理泛型类型并进行类型推断的方式,无论如何,你都会被困在一堆样板上。上面的内容可能就像你能够获得的那样简洁。