0

Suppose you have the following Either[A1,B2] instance where A1 and B2 are maped to match Either[A,B], where A and B have a common subtype S. Is there a way to easily narrow down the types A and B to S?

isaias-b
  • 2,255
  • 2
  • 25
  • 38

1 Answers1

0

You can use fold with the identity function on both sides. Here is an example:

import com.github.nscala_time.time.Imports._
import play.api.libs.json._
import scala.util.control.Exception._

val parsed = catching(classOf[IllegalArgumentException]) either DateTime.parse(str)
val mapped: Either[JsError, JsSuccess[DateTime]] = parsed
  .right.map(JsSuccess(_))
  .left.map(t => JsError(t.getMessage))
val fold: JsResult[DateTime] = mapped.fold(identity, identity)

In this case you start with an Either[Throwable, DateTime] which is transformed into an Either[JsError, JsSuccess[DateTime]]. Both sides have the common subtype JsResult[DateTime].

The types can be inferred completely in this case. After inlining the variables the code can be reduced to this:

(catching(classOf[IllegalArgumentException]) either DateTime.parse(str))
  .right.map(JsSuccess(_))
  .left.map(t => JsError(t.getMessage))
  .fold(identity, identity)
isaias-b
  • 2,255
  • 2
  • 25
  • 38
  • 1
    You should be able to just do something like `parsed.fold(t => JsError(t.getMessage), JsSuccess(_))`. – Karl Bielefeldt Mar 03 '17 at 16:40
  • You are right in this case and also in general: it is possible to gather both left and right mapping functions and provide it to `fold`! – isaias-b Mar 03 '17 at 16:59