5

I have a template using a valueObject that might be one of two flavours depending on where it is used in our app. So I am importing it as an Either:

valueObject: Either[ ObjectA, ObjectB ]

Both objects have an identically named property on them so I would like to retrieve it just by calling

valueObject.propertyA

Which doesn't work.

What is the most concise/ best way of doing this?

Liam
  • 27,717
  • 28
  • 128
  • 190
xeno.be
  • 91
  • 1
  • 10
  • Do the two object share a common superclass / trait with propertyA defined? or do they just "happen" to have that common property? – Tzach Zohar Jul 06 '16 at 11:05
  • They extend a common trait. The common property is however not defined on the trait - there is a third child that doesn't require it - but if that solves my problem elegantly I could include it there. – xeno.be Jul 06 '16 at 11:09
  • 1
    Maybe you could use `fold` – jilen Jul 06 '16 at 11:21

2 Answers2

10

Assuming the two objects have the same type (or a supertype / trait) that defines that property - you can use merge which returns left if it exists and right otherwise, with the lowest common type of both:

scala> class MyClass {
 | def propertyA = 1
 | }
defined class MyClass

scala> val e1: Either[MyClass, MyClass] = Left(new MyClass)
e1: Either[MyClass,MyClass] = Left(MyClass@1e51abf)

scala> val e2: Either[MyClass, MyClass] = Right(new MyClass)
e2: Either[MyClass,MyClass] = Right(MyClass@b4c6d0)

scala> e1.merge.propertyA
res0: Int = 1

scala> e2.merge.propertyA
res1: Int = 1
Tzach Zohar
  • 37,442
  • 3
  • 79
  • 85
2

Using fold

Assuming the two objects do not share a common supertype that holds the property/method, then you have to resort to fold:

scala> case class A(a: Int)
defined class A

scala> case class B(a: Int)
defined class B

scala> def foldAB(eab: Either[A,B]): Int = eab.fold(_.a,_.a)
foldAB: (eab: Either[A,B])Int
   
scala> foldAB(Left(A(1)))
res1: Int = 1

scala> foldAB(Right(B(1)))
res2: Int = 1

Pattern matching

Another possibility is to use pattern matching:

scala> def matchAB(eab: Either[A,B]): Int = eab match { case Left(A(i)) => i; case Right(B(i)) => i}
matchAB: (eab: Either[A,B])Int

scala> matchAB(Left(A(1)))
res3: Int = 1

scala> matchAB(Right(B(1)))
res4: Int = 1
Community
  • 1
  • 1
ziggystar
  • 28,410
  • 9
  • 72
  • 124