The case class aliasing type in Scala 2.10

I use Scala 2.10.2 and have two case classes that have the same fields:

case class Foo(id: String, name: String) case class Bar(id: String, name: String) 

I would like to do something like this:

 case class Thing(id: String, name: String) type Foo = Thing type Bar = Thing 

This compiles, but when I try to create Foo , I get:

 scala> Bar("a", "b") <console>:8: error: not found: value Bar Bar("a", "b") ^ 

Does type antialiasing work with case classes?

+7
scala
source share
4 answers

When you create a case class, Scala automatically creates a companion object for it. In your code, you define an alias for the type Thing , i.e. Thing class only. Your Thing companion object still has only one name and no aliases.

One way to fix this is to create a reference to a companion object (rather than a type alias) as follows:

 scala> val Bar = Thing Bar: Thing.type = Thing scala> Bar("a", "b") res1: Thing = Thing(a,b) 

Another way to fix this is to rename the imported object with import package.{Thing => Bar} .

+12
source share
 case class Thing(id: String, name: String) type Foo = Thing type Bar = Thing 

if you say new Bar("a","b") , it will work

+4
source share

Enter aliases only an alias of the type, and not any companion object that can supply factory methods (regardless of whether you write this factory method yourself or get it "free" from the compiler).

On the other hand, when importing actions with names, and if there are several objects associated with a given name, the import of this name brings into each referent of the imported name. In addition, you can rename upon import, and you can do this multiply, so ...

 scala> object Stuff { case class Thing(id: String, name: String) } defined module Stuff scala> import Stuff.Thing import Stuff.Thing scala> import Stuff.{Thing => Foo} import Stuff.{Thing=>Foo} scala> import Stuff.{Thing => Bar} import Stuff.{Thing=>Bar} scala> val thing1 = Thing("fing", "fang") thing1: Stuff.Thing = Thing(fing,fang) scala> val foo1 = Foo("yes", "no") foo1: Stuff.Thing = Thing(yes,no) scala> val bar1 = Bar("true", "false") bar1: Stuff.Thing = Thing(true,false) 

This is not useful for rendering via toString , though, as you can see.

+4
source share

Do you want Foo and Bar be distinguishable (as in the case of different classes of cases) or not? If so, and you just want to avoid repeating the list of fields, you can do this:

 case class Foo(thing: Thing) case class Bar(thing: Thing) 

But this will obviously make them less convenient to use in pattern matching or access fields. Access to the fields can be slightly improved:

 trait ThingWrapper { def thing: Thing def id = thing.id def name = thing.name } case class Foo(thing: Thing) extends ThingWrapper case class Bar(thing: Thing) extends ThingWrapper 
0
source share

All Articles