0

I have 3 classes from external lib (A, B, C) both extends Object

How can I define a type of variable that can hold values only of this 3 types (and their subclasses)? like

val myVal: A or B or C (or their sub-classes if this is possible)

1 Answers1

1

Scala does't provide union types, but you can use Coproduct, i.e. a generalization of the Either type.

Shapeless provides a nice implementation.

Here's an example straight from the shapeless's feature overview

scala> type ISB = Int :+: String :+: Boolean :+: CNil
defined type alias ISB

scala> val isb = Coproduct[ISB]("foo")
isb: ISB = foo

scala> isb.select[Int]
res0: Option[Int] = None

scala> isb.select[String]
res1: Option[String] = Some(foo)

In the example, you define a Coproduct type ISB, then you can use select to extract the type you're looking for. The result of select is an Option since isb may or may not hold an instance of that type.


Other approaches, that don't involve libraries, can be found here: How to define "type disjunction" (union types)? and in this excellent blog post by Miles Sabin (author of shapeless): http://milessabin.com/blog/2011/06/09/scala-union-types-curry-howard/

Community
  • 1
  • 1
Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
  • is there any solution for pure scala? (without dependencies) –  Sep 16 '15 at 09:46
  • @paul_di you don't have a Coproduct directly, but you can use several approaches to mimic a disjunction in vanilla scala. Here's a useful reference: http://stackoverflow.com/questions/3508077/how-to-define-type-disjunction-union-types – Gabriele Petronella Sep 16 '15 at 09:49