How to smooth Try [Option [T]]

I want to smooth a Try[Option[T]] into 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?

+6
source share
4 answers

You can try something like this a little neat:

 val t = Try(Some(1)) val tt = t.flatMap{ case Some(i) => Success(i) case None => Failure(new Exception("parsing error")) } 

In general, this will 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 converting Option to Try to use a flat map.

+6
source

Convert attempt, then flatten:

 val t = Try(Some(1)) val o = t.toOption.flatten 
+1
source

Using getOrElse , you can 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 do it even shorter, but perhaps at the cost of functional cleanliness (throwing is a side effect) and performance (due to throwing / trapping):

 def flattenTry[T](t: Try[Option[T]]): Try[T] = { Try(t.get getOrElse { throw new Exception("parsing error") }) } 
0
source

One possible way is to use Try(o.get) to convert o: Option to o: Try .

This is very eloquent, but it throws and throws an exception when handling None , which can sometimes be a performance issue (or sometimes it concerns ideological / code rules). However, the code is so concise and well readable, I think it's worth mentioning:

 def flattenTry[T](t: Try[Option[T]]) : Try[T] = { t.flatMap(o => Try(o.get)) } 

Note. It is not recommended to use it, but for completeness: an even shorter version is possible that throws / catches even if Try is a failure:

 def flattenTry[T](t: Try[Option[T]]) : Try[T] = { Try(t.get.get) } 
0
source

Source: https://habr.com/ru/post/958860/


All Articles