2010-09-24 5 views

risposta

9

Non proprio possibile, come dici tu, ma è possibile farlo utilizzando il modello tipo di classe. Ad esempio, dal 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

Questo funziona se la classe e l'oggetto sono compagni. Su REPL, se si digita ciascuno su una linea diversa (cioè, un "risultato" appare tra di loro), non sono compagni. È possibile digitare è come qui di seguito, però:

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

Grazie, inoltre riferimento http://ropas.snu.ac.kr/~bruno/papers/TypeClasses.pdf – oluies

+1

@Brent Come ho detto per e-mail, questo è probabilmente il risultato di digitare la classe un oggetto su linee diverse. Vedi la mia modifica. –

5

È possibile ottenere un piccolo chilometraggio dal tipo Either. Tuttavia, l'una o l'altra gerarchia è sigillata e la gestione di più di due tipi diventa ingombrante.

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

Un'altra soluzione è classi involucro:

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)} 
Problemi correlati