2010-09-24 75 views
8

我設置多個或運算類型界限是否有可能做這樣的事情在Scala如何在斯卡拉

class MyTest { 
    def foo[A <: String _or_ A <: Int](p:List[A]) = {} 
} 

也就是說,類型A可能是StringInt。這可能嗎?

(類似問題here

回答

9

不是因爲你把它真的有可能,但你可以使用類型類模式去做。例如,從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) 
^ 

編輯

這個工作,如果類和對象的同伴。在REPL上,如果您在不同的行上鍵入每一行(即在它們之間出現「結果」),則它們不是同伴。你可以像下面鍵入,雖然:

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

謝謝,也引用http://ropas.snu.ac.kr/~bruno/papers/TypeClasses.pdf – oluies 2010-09-24 21:58:37

+1

@Brent正如我通過電子郵件所說的,這可能是因爲在不同的行上輸入對象。看我的編輯。 – 2010-09-25 20:44:34

5

您可以從任一種類型中獲得一小部分里程。然而,Either層次結構是密封的,處理兩種以上類型變得麻煩。

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

另一種解決方案是包裝類:

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