Mattia Micomonaco
Mattia Micomonaco

Reputation: 230

Scala flatten class

I have defined the following classes in Scala:

case class Info {
    name: String,
    age: Int,
    dept: String
}


case class Foo {
    id: String,
    info: Info    
}

Is there a way to obtain automatically the following class from Foo and Info:

case class FlatFoo {
    id: Option[String],
    name: Option[String],
    age: Option[Int].
    dept: Option[String]
}

Upvotes: 0

Views: 268

Answers (1)

Odomontois
Odomontois

Reputation: 16318

This looks like a task for a very hardcore macro.
But I wonder if you just want to shorten your field accessors like obj.fieldX.fieldY.fieldZ....
In that case you might be interested in concept named Lens. Which is beautifully implemented in monocle library

Consider such definition of your case classes:

import monocle.macros.Lenses

@Lenses
case class Info(name: String,
                age: Int,
                depts: List[String]
               )
@Lenses
case class User(id: String,
               info: Info
              )

That @Lenses attribute generates special functional getter&setter for each field . Those lenses are located implicitly in companion object. But you could add your own, composing existent.

import monocle.function.Index._
import monocle.std.list._
object User {
  val name = info ^|-> Info.name
  val age = info ^|-> Info.age
  val mainDept = info ^|-> Info.depts ^|-? index(0)
}

Now having

val oleg = User("odomontois", Info("Oleg", 23, List("python", "ABAP")))

You can see that

User.mainDept.getOption(oleg) == Some("python")

(User.age.set(28) andThen User.mainDept.set("scala")) (oleg) ==
  User("odomontois",Info("Oleg",28,List("scala", "ABAP")))

Upvotes: 5

Related Questions