Suppose you have the following Either[A1,B2]
instance where A1
and B2
are map
ed 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
?
Asked
Active
Viewed 170 times
1 Answers
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
-
1You 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