views:

183

answers:

2

Is it possible to do this sort of thing in Scala?

+2  A: 

Yes!

Scala supports "lazy vals" as a way to defer calculation of a value until it's actually used. Much of the Scala 2.8 library is capable of working with lazily-defined collections.

Kevin Wright
+8  A: 
def quicksort[A](xs: Stream[A])(implicit o: Ordering[A]): Stream[A] = {
  import o._ 
  if (xs.isEmpty) xs else {
      val (smaller, bigger) = xs.tail.partition(_ < xs.head)
      quicksort(smaller) #::: xs.head #:: quicksort(bigger)
  }
}

It can be done with views as well, though it's bound to be much slower:

def quicksort[A](xs: List[A])(implicit o: Ordering[A]) = {
  import o._
  def qs(xs: SeqView[A, List[A]]): SeqView[A, Seq[_]] = if (xs.isEmpty) xs else {
    val (smaller, bigger) = xs.tail.partition(_ < xs.head)
    qs(smaller) ++ (xs.head +: qs(bigger))
  }
  qs(xs.view)
}
Daniel
Thanks but I would like to see the list-views implementation as well.
Mahesh
@Mahesh The view implementation turns out to be tougher than I first imagined. I'll keep trying to see if something works.
Daniel
@Mahesh Ok, got the problem ironed out. I was forgetting the `.head` on the concatenation line... Silly me.
Daniel
@Daniel: can we replace the first line with `quicksort[A <% Ordering[A]](xs: List[A]) = {` ?
Aymen
@Aymen An `Ordering` is not as flexible as an `Ordered`. Other than that, yes, and get rid of the `import` on the second line.
Daniel