简体   繁体   中英

A more functional way to write this?

I was thinking about something, I wrote this trait with two classes extending it and another class that may contain them:

sealed trait MainObj
case object subObj1 extends mainObj
case Object subObj2 extends mainObj

case class AnotherClass(val mo: Option[MainObj], val amount: Int)

Now let's say I wanted to write a function that added the amounts in two AnotherClass objects but only if the optional MainObj inside each of them were the same type. Like only add if both are subObj1 .

So I could do something like this:

def add(one: AnotherClass, two: AnotherClass): AnotherClass = one. mo, two.mo match {
  case (Some(x), Some(y)) if i and x are the same class => return a `AnotherClass` with the two integers added from `one` and `two`
etc..

I wondered whether there was another way of doing this? I don't know whether this is a "functional" way of doing it or whether there is a less verbose way?

I ask because essentially I could write some more methods like subtract , multiply , etc ... and I have some very common code.

I could extract that common code and write a function that simply takes two of the subObj s and an operation and then apply that operation on the two objects, but that only abstracts out the common operation, could the main pattern matching part be written differently that may be considered more concise(for lack of a better word)?

Just add the 'add' method to the case class :

sealed trait MainObj
case object SubObj1 extends MainObj
case object SubObj2 extends MainObj

case class AnotherClass(val mo: Option[MainObj], val amount: Int){
  def add(that:AnotherClass):AnotherClass = {
    if (that.mo == this.mo)
      this.copy(amount = this.amount + 1)
    else
      this
  }
}

val x = AnotherClass(Some(SubObj1), 1)
val y = AnotherClass(Some(SubObj1), 1)
val z = AnotherClass(Some(SubObj2), 1)

scala> x add y
res5: AnotherClass = AnotherClass(Some(SubObj1),2)
scala> x add z
res6: AnotherClass = AnotherClass(Some(SubObj1),1)

scala> val l = List(x,y,z)
l.reduce ( _ add _)
res7: AnotherClass = AnotherClass(Some(SubObj1),2)
val mo = two.mo
one match {
   case AnoterClass(`mo`, am) =>
        one.copy(amount = am + two.amount)
   case _ => ???
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM