2010-09-24 24 views

Respuesta

9
No

realmente posible como usted dice, pero puede hacerlo utilizando el patrón de clase de tipo. Por ejemplo, desde 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) 
^ 

EDITAR

Esto funciona si la clase y el objeto son compañeros. En REPL, si escribe cada uno en una línea diferente (es decir, aparece un "resultado" entre ellos), no son compañeros. Puede escribir que, como a continuación, sin embargo:

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

Gracias, también la referencia http://ropas.snu.ac.kr/~bruno/papers/TypeClasses.pdf – oluies

+1

@Brent Como dije por correo electrónico, esto es probablemente el resultado de escribir la clase de un objeto en diferentes líneas. Ver mi edición –

5

Puede obtener un poco de millaje del tipo Cualquiera. Sin embargo, la jerarquía de Either está sellada y manejar más de dos tipos resulta engorroso.

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

Otra solución es clases de contenedor:

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)} 
Cuestiones relacionadas