Question

Est-il possible de faire quelque chose comme ça dans Scala :

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

C'est, le type A pourrait être un String ou Int. Est-ce possible?

(question similaire )

Était-ce utile?

La solution

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

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, bien que:

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

Autres conseils

Vous pourriez obtenir un peu de kilométrage du type ou l'autre. Cependant, la hiérarchie est soit scellée et traiter plus de deux types devient lourd.

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

Une autre solution est wrapper cours:

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

Il y a ce hack:

implicit val x: Int = 0
def foo(a: List[Int])(implicit ignore: Int) { }

implicit val y = ""
def foo(a: List[String])(implicit ignore: String) { }

foo(1::2::Nil)
foo("a"::"b"::Nil)

Voir http: // michid .wordpress.com / 2010/06/14 / travail autour du type d'effacement des ambiguïtés-scala /

Et aussi cette question .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top