2011-07-13 15 views
13

Scala'da yazım desenini kullanıyorum varsayalım. Şimdiye kadar iyiTip desenini altyazı ile nasıl birleştirebilirim?

Welcome to Scala version 2.9.0.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26). 

scala> trait Foo[T] { def foo(t: T) } 
defined trait Foo 

scala> def foo[T : Foo](t: T) { implicitly[Foo[T]].foo(t) } 
foo: [T](t: T)(implicit evidence$1: Foo[T])Unit 

scala> class C 
defined class C 

scala> foo(new C) 
<console>:11: error: could not find implicit value for evidence parameter of type Foo[C] 
     foo(new C) 
     ^

scala> implicit object FooC extends Foo[C] { override def foo(c: C) { println("it's a C!") } } 
defined module FooC 

scala> foo(new C) 
it's a C! 

: Ben typeclass Foo bir sınıf C parçası haline şekli aşağıdaki gibidir. Ama C sınıfının bir alt sınıfı D olduğunu varsayalım, ben de typeclass "in" olmak D örneklerini istiyorum:

scala> class D extends C 
defined class D 

scala> foo(new D) 
<console>:13: error: could not find implicit value for evidence parameter of type Foo[D] 
     foo(new D) 
     ^

Doh! Bu işi, D için bir yazım hatası örneği sağlamak zorunda kalmadan nasıl yapabilirim?

+0

cevapsız Bu hemen hemen http yineleniyor: // stackoverflow. com/questions/3869991/type-class-pattern-in-scala-dikkate-dikkate-devralma –

cevap

14

Sadece C için sorunu düzeltmek istemediğinize bağlı, bunun için farklı olası çözümler vardır, yoksa bütün typeclass için sorunu gidermek isteyip. yapmak,

implicit def CIsFoo[T <: C]: Foo[T] = 
    new Foo[T] { override def foo(t: T) { println("it's a C!") } } 

Foo tüm düzeltmek için o kontravaryant:

yerine sadece implicit object FooC ... ait C için söylediğimiz

trait Foo[-T] { def foo(t: T) } 

Veya eğer nedense yapamazsın veya don' ortama uyum #scala için

def foo[T](t: T)(implicit foo: Foo[_ >: T]) = 
    foo.foo(t) 

(teşekkür: t ile def foo... yerine, bunu yapmak ister . Yardımlarını s Daniel Sobral ve Stefan Zeiger)

"Foo kontravaryant yapmak" çözümü içerecek şekilde 2011 20 Eylül GÜNCELLEME, ben

+1

Burada gizlenen başka bir soru var ... Ya D dan biraz daha farklı muamele görmek istiyorum, * ama * bazı ortak kod paylaşın ! – jsuereth

+3

@jsuereth Hiçbir şey, 'C' için yaptığınız gibi 'D' için 'örtük bir nesne' FooD 'beyan etmenizi engeller ve FooC'deki' FooD 'yöntemlerini çağırır. –

+1

Aslında onu denemelisin. Önceliklerle uğraşmadığınız sürece 'Çelişen örtülü ithalat'. Tam çözüm, güzel kazan-platiye benziyor ve muck etmek için sinir bozucu olabilir. – jsuereth