2010-09-24 9 views

Répondre

9

Pas vraiment possible comme vous le dites, mais vous pouvez le faire en utilisant le modèle de classe de type. Par exemple, à partir here:

sealed abstract class Acceptable[T] 
object Acceptable { 
    implicit object IntOk extends Acceptable[Int] 
    implicit object LongOk extends Acceptable[Long] 
} 

def f[T: Acceptable](t: T) = t 

scala> f(1) 
res0: Int = 1 

scala> f(1L) 
res1: Long = 1 

scala> f(1.0) 
<console>:8: error: could not find implicit value for parameter ev: Acceptable[Double] 
f(1.0) 
^ 

EDIT

Cela fonctionne si classe et objets sont des compagnons. Sur REPL, si vous tapez chacun sur une ligne différente (par exemple, un "résultat" apparaît entre eux), ils ne sont pas des compagnons. Vous pouvez taper comme ci-dessous, cependant:

scala> sealed abstract class Acceptable[T]; object Acceptable { 
    | implicit object IntOk extends Acceptable[Int] 
    | implicit object LongOk extends Acceptable[Long] 
    | } 
defined class Acceptable 
defined module Acceptable 
+0

Merci, référence également http://ropas.snu.ac.kr/~bruno/papers/TypeClasses.pdf – oluies

+1

@Brent Comme je l'ai dit par e-mail, il s'agit probablement d'un typage de la classe d'un objet sur des lignes différentes. Voir ma modification. –

5

Vous pourriez obtenir un peu de kilométrage du type Sither. Cependant, la hiérarchie Either est scellée et la gestion de plus de deux types devient fastidieuse.

scala> implicit def string2either(s: String) = Left(s) 
string2either: (s: String)Left[String,Nothing] 

scala> implicit def int2either(i: Int) = Right(i) 
int2either: (i: Int)Right[Nothing,Int] 

scala> type SorI = Either[String, Int] 
defined type alias SorI 

scala> def foo(a: SorI) {a match { 
    |  case Left(v) => println("Got a "+v) 
    |  case Right(v) => println("Got a "+v) 
    | } 
    | } 
foo: (a: SorI)Unit 

scala> def bar(a: List[SorI]) { 
    | a foreach foo 
    | } 
bar: (a: List[SorI])Unit 

scala> 

scala> foo("Hello") 
Got a Hello 

scala> foo(10) 
Got a 10 

scala> bar(List(99, "beer")) 
Got a 99 
Got a beer 
2

Une autre solution est classes d'emballage:

case class IntList(l:List[Int]) 
case class StringList(l:List[String]) 

implicit def li2il(l:List[Int]) = IntList(l) 
implicit def ls2sl(l:List[String]) = StringList(l) 

def foo(list:IntList) = { println("Int-List " + list.l)} 
def foo(list:StringList) = { println("String-List " + list.l)}