通过第二个论点来讨论

时间:2013-10-10 14:00:27

标签: scala

我需要使用几种方法来实现快速排序以选择数据透视表,因此我实现了一个将数据透视选择器作为参数的例程。但是具体实现的定义包含许多样板,是否有更简洁的方法来定义它们?

  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中有类似的内容吗?

2 个答案:

答案 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处理泛型类型并进行类型推断的方式,无论如何,你都会被困在一堆样板上。上面的内容可能就像你能够获得的那样简洁。