2014-09-08 56 views
8

İki farklı sınıf için aynı örtük siparişi tanımlamanın bir yolu var mı?Scala Kapalı Sipariş Verme

Aşağıdaki satırlarda bir şeyler yapmaya çalıştım ancak siparişi algılamıyor.

abstract class Common 
case class A extends Common 
case class B extends Common 

implicit val KeyOrdering = new Ordering[Common] { 
    override def compare(x: Common, y: Common): Int = { 
     x.toString.compareTo(y.toString) 
    } 
} 
+1

'extends' bir saklıdır olduğunu anahtar kelime ve tür değil. "Ortak" mı demek istiyorsun? – Kigyo

+0

Yup, demek istediğim buydu. Bunu işaret ettiğin için teşekkürler. – Olshansk

+0

Evet, bunun neden işe yaramadığından emin değilim. 'List (A(), B()). Sıralanmış 'hiçbir dolaylı emri bulunamadığını, ancak açıkça' List (A(), B()). '(KeyOrdering)' işlerinin yapılacağını belirtir. – Kigyo

cevap

22

, listenizin çıkarsama yoluyla türü - iki elemanlarının en küçük alt sınır -. tutmadığı çünkü Product with Serializable with Common olduğu scala.Ordering gibi onun tipi parametresine kontravaryant değildir, örtülü çözünürlük başarısız Bu Ordering[Common] <: Ordering[Product with Serializable with Common].

her zaman göz altında örtük parametrenin kesin türüne sahip böylece örtük sipariş yazarak bu çalışabilirsiniz:

abstract class Common 
case class A() extends Common 
case class B() extends Common 

object Common { 
    implicit def ordering[A <: Common]: Ordering[A] = new Ordering[A] { 
    override def compare(x: A, y: A): Int = { 
     x.toString.compareTo(y.toString) 
    } 
    } 
} 

Ya concision için

:

object Common { 
    implicit def ordering[A <: Common]: Ordering[A] = Ordering.by(_.toString) 
} 
+2

Diğer cevabınız tarafından uzman olduğunuzu görüyorum. http://stackoverflow.com/questions/19345030/easy-idiomatic-way-to-define-ordering-for-a-simple-case-class –

+0

Bu konuyla ilgili bir notla cevabını güncelledim. . –

2

A ve B için (ancak bunlardan yalnızca biri için) vaka sınıfını kaldırırsanız, o zaman çalışır. List(A(), B()).sorted için, A ve B için temel sınıf C olduğu için (A ve B'nin her iki durum sınıfı olması nedeniyle),için Ordering bulmak başarısız olur.

iki farklı baz türlerinin unsurları ile bir liste oluşturuyorsanız

, sana bunları kullanmadan önce elemanlarını bildirmek (veya tip C döndüren bazı işlevinden onları hangi tip List[C] bir listesini istiyorum varsayalım.

@ntn tarafından belirtildiği gibi
val a: C = A() 
val b: C = B() 
List(a,b).sorted