Reputation: 8281
I want to flatten a Try[Option[T]]
into a Try[T]
Here is my code
def flattenTry[T](t: Try[Option[T]]) : Try[T] = {
t match {
case f : Failure[T] => f.asInstanceOf[Failure[T]]
case Success(e) =>
e match {
case None => Failure[T](new Exception("Parsing error"))
case Some(s) => Success(s)
}
}
}
Is there a better way ?
Upvotes: 6
Views: 1739
Reputation: 34403
One possible way is to use Try(o.get)
to convert o: Option
to o: Try
.
This is very concise, but throws and catches exception when handling None
, which might perhaps be a performance concern sometimes (or sometimes an ideological / code rules concern). Still, the code is so concise and well readable I think it is worth mentioning:
def flattenTry[T](t: Try[Option[T]]) : Try[T] = {
t.flatMap(o => Try(o.get))
}
Note: not that I recommend using it, but for completeness: even a shorter version is possible, which throws / catches even when Try
is a failure:
def flattenTry[T](t: Try[Option[T]]) : Try[T] = {
Try(t.get.get)
}
Upvotes: 0
Reputation: 380
Using getOrElse
, you could also write:
def flattenTry[T](t: Try[Option[T]]): Try[T] = {
t flatMap { o => o map (Success(_)) getOrElse Failure(new Exception("parsing error")) }
}
You could make this even shorter, but possibly at the cost of functional purity (throwing is a side-effect) and performance (due to throwing/catching):
def flattenTry[T](t: Try[Option[T]]): Try[T] = {
Try(t.get getOrElse { throw new Exception("parsing error") })
}
Upvotes: 0
Reputation: 35443
You could try something like this which is a little neater:
val t = Try(Some(1))
val tt = t.flatMap{
case Some(i) => Success(i)
case None => Failure(new Exception("parsing error"))
}
More generically, this would be:
def flattenTry[T](t: Try[Option[T]]) : Try[T] = {
t.flatMap{
case Some(s) => Success(s)
case None => Failure(new Exception("parsing error"))
}
}
The trick is to convert the Option
into Try
for using flatmap.
Upvotes: 6