2010-09-24 11 views

Odpowiedz

9

Nie bardzo możliwe, jak to ująłeś, ale można to zrobić przy użyciu wzorca klasy typu. Na przykład, od 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

To działa, jeśli klasa i obiekt są towarzyszami. W REPL, jeśli wpiszesz każdą z nich w innym wierszu (tzn. Pojawi się między nimi "wynik"), nie są one towarzyszami. Można wpisać go jak poniżej, choć:

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

Dzięki, również odwołać http://ropas.snu.ac.kr/~bruno/papers/TypeClasses.pdf – oluies

+1

@Brent Tak jak powiedziałem przez e-mail, jest to prawdopodobnie wynikiem wpisania klasy obiektu na różnych liniach. Zobacz moją edycję. –

5

Możesz uzyskać niewielki przebieg z dowolnego typu. Jednak obie hierarchie są zapieczętowane, a obsługa więcej niż dwóch typów staje się uciążliwa.

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

Innym rozwiązaniem jest klas Wrapper:

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)} 
Powiązane problemy