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
}
}
Unfortunately you can not declare type as type U[T] = T <% Ordered[T]
. This will not work and even will not compile.
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 :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With