2017-02-02 1 views
0

J'essaie d'étendre la fonction mSort générique pour travailler avec implicits et les limites de type. Cela fonctionne bien quand j'utilise un trait générique pour étendre Ordered mais pas avec une classe abstraite. Peux-tu aider s'il te plait?Scala typebounds ne fonctionne pas avec la classe abstraite, mais fonctionne avec des traits

object MergeSort extends App { 

    // With Abstract Class 
    abstract class Id(id: Int) extends Ordered[Id] { 
    override def compare(that: Id): Int = this.id.compareTo(that.id) 
    } 
    case class Emp(id: Int, name: String) extends Id(id) { 
    //override def compare(that: Emp): Int = this.name.compareTo(that.name) 
    } 

//// With Traits: Works fine 
// trait Id extends Ordered[Id]{ 
// val id: Int 
// override def compare(that: Id): Int = this.id.compareTo(that.id) 
// } 
// case class Emp(id: Int, name: String) extends Id { 
// //override def compare(that: Emp): Int = this.name.compareTo(that.name) 
// } 


    object MSort { 
    def msort[T <% Ordered[T]](list: List[T])(implicit less: (T, T) => Boolean): List[T] = { 
     def merge(xs: List[T], ys: List[T]): List[T] = { 
    (xs, ys) match { 
     case (Nil, _) => ys 
     case (_, Nil) => xs 
     case (x :: xs1, y :: ys1) => if (less(x, y)) x :: merge(xs1, ys) else y :: merge(xs, ys1) 
    } 
     } 
     val n = list.length/2 
     if(n==0) list 
     else { 
    val (ys, zs) = list.splitAt(n) 
    merge(msort(ys), msort(zs)) 
     } 
    } 
    } 

    implicit def less [T <% Ordered[T]] (x: T, y: T): Boolean = x <= y 
// MSort.msort[Int](List(6, 3, 9, 1)).foreach(println) 
// MSort.msort[Char](List('a', 'z', 'Z', 'D')).foreach(println) 
// MSort.msort[String](List("appolo", "lunar", "Zapplin", "Kafka")).foreach(println) 
// MSort.msort[Double](List(12.3, 14, 19.3, -32.443)).foreach(println) 
    MSort.msort[Id](List(Emp(7, "appolo"), Emp(2, "lunar"), Emp(9, "Zapplin"), Emp(1, "Kafka"))).foreach(println) 

} 

Erreur:

Error:(5, 66) value id is not a member of MergeSort.Id 
override def compare(that: Id): Int = this.id.compareTo(that.id) 

Répondre

4

Sans l'id "val" est juste un arg constructeur, pas une propriété de la classe.

abstract class Id(id: Int) extends Ordered[Id] { 
    override def compare(that: Id): Int = this.id.compareTo(that.id) 
} 

Cela signifie aussi que votre argument id dans Emp doit être signalée comme une dérogation

case class Emp(override val id: Int, name: String) extends Id(id) { 
    //override def compare(that: Emp): Int = this.name.compareTo(that.name) 
}