Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Case classes in Scala with behavior

Tags:

class

case

scala

I have a Scala case class that has certain val's as parameters. I have a couple of methods that makes use of this case class. Assuming that my case class is defined as follows:

case class CaseA(a: Int, b: List[CaseB])
case class CaseB(a: Int, b: text, c: Boolean)

Both the CaseA and CaseB represent the domain model of my case classes. But as I use them in my application, I want to add some behavior to CaseA based on CaseB's Boolean field. For example., let us suppose that in CaseA, the val b has 4 CaseB objects. I want to add a behavior that would run through b and tell me if any one of the element in CaseB has the val c set to true.

What I did come up is with the following implementation of CaseA:

case class CaseA(a: Int, b: List[CaseB], c: Boolean)

But the problem with this approach is that when I load my CaseA object from the database, I do not need to have the val c as the val c is computed and not part of CaseA object. I went a step further and modified my CaseA to look like as below:

case class CaseA(a: Int, b: List[CaseB], c: Option[Boolean])

I can see that it is already getting ugly. How can I add behavior to my case classes so that the val c need not be part of the CaseA object and it is rather computed everytime at runtime?

like image 309
joesan Avatar asked Jan 11 '23 16:01

joesan


1 Answers

I would use a lazy value in case you don't need the c for all elements

case class CaseB(a:Int,b:String,c:Boolean)
case class CaseA(a:Int,b:List[CaseB]){
    lazy val c = b exists (_.c)
}

val ca = CaseA(42, List( 
    CaseB(1,"hello",false),
    CaseB(2,",",false),
    CaseB(3,"world",true))
    )

println(ca.c)

To answer some of your comment questions, if you want to use a mixin-trait, you can do something like the following:

case class CaseB(a:Int,b:String,c:Boolean)
case class CaseA(a:Int,b:List[CaseB])
trait CanCheck extends CaseA{
    lazy val c = b exists (_.c)
}

val ca = new CaseA(42, List( 
    CaseB(1,"hello",false),
    CaseB(2,",",false),
    CaseB(3,"world",true))
    ) with CanCheck

println(ca.c)

Notice that you need to use the new keyword to make this work

like image 79
Felix Avatar answered Jan 18 '23 13:01

Felix