Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refactoring boilerplate type constraints

Tags:

scala

I have an object with a bunch of related routines and all their declarations look the same, something like

object Sorting {
  def qsort[a <% Ordered[a]] ....

  def partition[a <% Ordered[a]] ...

  def qselect[a <% Ordered[a]] ...
}

Is there a way to specify the type constraint in one place and reduce declarations to something like qsort[a](xs: Stream[a]) or even better just qsort(xs: Stream[a]) ?

For the time being I've decided to roll with implicit classes

object Implicits {
  implicit class SortableArray[a <% Ordered[a]](xs: Array[a]) {
    def qsort = {...}
  }
}

object Application {
  import Implicits._
  def main(args: Array[String]) = {
    val xs = Array(1,2,3)
    xs.qsort
  }
}
like image 405
synapse Avatar asked Oct 02 '22 18:10

synapse


1 Answers

Unfortunately you can not declare type as type U[T] = T <% Ordered[T]. This will not work and even will not compile.

But, there are some workarounds you can apply to your code

Confider this think-flow:

As described here:

def f[A <% B](a: A) = a.bMethod

is the same as

def f[A](a: A)(implicit ev: A => B) = a.bMethod

and this

def g[A : B](a: A) = h(a)

is the same as

def g[A](a: A)(implicit ev: B[A]) = h(a) .

So going back to you example:

def qsort[A <% Ordered[A]] = ???

... is translated to:

def qsort[A](implicit ev: A => Ordered[A]) = ???

... now you can introduce type parameter like:

type O[A] = A => Ordered[A]

... and use it as:

def gsort[A] (implicit ev: O[A])

... which can be simplified into:

def gsortX[A : O]

Then all your code you can write as:

Before

object Sorting {

  def qsort[A <% Ordered[A]] = ???

  def partition[A <% Ordered[A]] = ???

  def qselect[A <% Ordered[A]] = ???
}

After

object Sorting {

  type O[A] = A => Ordered[A]

  def qsort[A: O] = ???

  def partition[A: O] = ???

  def qselect[A: O] = ???
}

Or even better using trait

trait Sorting[A] {
  type O = A => Ordered[A]
  implicit def f : O

  def qsort = ???

  def partition = ???

  def qselect = ???
}

I hope this helps somehow :)

like image 166
pawel.panasewicz Avatar answered Oct 13 '22 11:10

pawel.panasewicz