0

i do some experiments with Scala types

and tried to do something like that:

case class Foo(name: String)
defined class Foo

scala> case class Bar(id: Int)
defined class Bar

scala> def process[A <: Foo with Bar](x: A) = println(x)
process: [T <: Foo with Bar](x: T)Unit

tried to run this:

scala> process[Foo](Foo("test"))
<console>:15: error: type arguments [Foo] do not conform to method process's type parameter bounds [T <: Foo with Bar]
           process[Foo](Foo("test"))

scala> process[Bar](Bar(1))
<console>:15: error: type arguments [Bar] do not conform to method process's type parameter bounds [T <: Foo with Bar]
       process[Bar](Bar(1))

how do i can do this correctly without trait addition?

trait Printable
class Foo extends Printable
class Bar extends Printable

def process(x: Printable) = println(x)

Not like this. Is there are some other ways?

Andrey Tyukin
  • 43,673
  • 4
  • 57
  • 93
HoTicE
  • 573
  • 2
  • 13
  • 1
    The linked duplicate question mentions several possibilities: 1) Overload `process`, one for `Foo`, one for `Bar`; 2) Use `Either` 3) Use `Any` / `AnyRef` with pattern matching. Then Daniel C. Sobral's answer proposes to 4) Use type-class witnesses to ensure that `process` accepts one the two explicitly whitelisted types. If you want real union types, you'll have to [use Dotty](https://dotty.epfl.ch/docs/reference/union-types.html) or wait for Scala 3. – Andrey Tyukin Jul 25 '18 at 12:19
  • `[A <: Foo with Bar]` means you want A to be subtype of Foo & Bar. You can't do that with classes. You could use traits instead `trait Foo trait Bar def process[A <: Foo with Bar](x: A) = println(x) process[Foo with Bar](new Object with Foo with Bar)` – Sergii Shevchyk Jul 25 '18 at 12:21
  • 1
    ok, i got it. Thanks! – HoTicE Jul 25 '18 at 12:35

0 Answers0