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 ?
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.
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") })
}
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)
}
Related
Im writing my own class Success or Error. I want to create a way to build SuccessOrError from Try and then use Try instead of ugly try-catch in flatMap. But I'm stuck at this point. How should I best write a function fromTry in order to be able to write like this?
case SuccessOrError.Success(v) ⇒ SuccessOrError.fromTry(Try(f(v)))
enum SuccessOrError[+V]:
case Success(x: V) extends SuccessOrError[V]
case Error(e : Throwable) extends SuccessOrError[V]
def flatMap[Q](f: V ⇒ SuccessOrError[Q]): SuccessOrError[Q] =
this match
case SuccessOrError.Success(v) ⇒ try f(v) catch case NonFatal(e) => SuccessOrError.Error(e)
case SuccessOrError.Error(e) ⇒ SuccessOrError.Error(e)
object SuccessOrError:
def fromTry[Q](f: Try[Q]): SuccessOrError[Q] = ???
Converting from Try to another error model is quite a common practice. Perhaps consider how they approach it in scala-cats library as inspiration
Validated
/**
* Converts a `Try[A]` to a `Validated[Throwable, A]`.
*/
def fromTry[A](t: Try[A]): Validated[Throwable, A] =
t match {
case Failure(e) => invalid(e)
case Success(v) => valid(v)
}
or Either
/**
* Converts a `Try[A]` to a `Either[Throwable, A]`.
*/
def fromTry[A](t: Try[A]): Either[Throwable, A] =
t match {
case Failure(e) => left(e)
case Success(v) => right(v)
}
or ApplicativeError
/**
* If the error type is Throwable, we can convert from a scala.util.Try
*/
def fromTry[A](t: Try[A])(implicit ev: Throwable <:< E): F[A] =
t match {
case Success(a) => pure(a)
case Failure(e) => raiseError(e)
}
Note the pattern (bad pun, applogies) of simply pattern matching on happy and unhappy cases, so we can try emulating it
def fromTry[Q](f: Try[Q]): SuccessOrError[Q] =
f match {
case scala.util.Failure(e) => SuccessOrError.Error(e)
case scala.util.Success(v) => SuccessOrError.Success(v)
}
How do you handle return types when we are catching exceptions? Are there any best practices?
class Test {
val emptymap = Map[Int,Int]()
val divisor = 100
def handleInt ( i : Int) : Map[Int, Int] = {
try {
val output = divisor / i
Map(divisor -> output)
} catch {
case e : ArithmeticException => e.printStackTrace(); emptymap
case e : NumberFormatException => e.printStackTrace(); emptymap
}
}
def handleIntTry ( i : Int) : Map[Int, Int] = {
val answer = Try(divisor / i)
answer match {
case x : Success[Int] => Map(divisor -> answer.get)
case x : ArithmeticException => { x.printStackTrace(); emptymap}
case x : NumberFormatException => { x.printStackTrace(); emptymap}
}
}
}
Are they both correct? which would be the better way to handle these situations?
The second is incorrect but for reasons which have nothing to do with "handling return types when we are catching exceptions".
It's pointless to use Try and then immediately match on the answer; it's just a more verbose and slower version of try-catch. Try is useful when you are going to pass it somewhere, or maybe combine multiple calculations.
Even neglecting that, the correct match would be
answer match {
case Success(x) => Map(divisor -> x)
case Failure(x) => { x.printStackTrace(); emptymap}
}
(no need to handle ArithmeticException and NumberFormatException separately if you are going to do the same in both cases).
What applies to both versions:
you create emptymap in advance, even if the exception isn't thrown.
Either way works. Here's a 3rd option.
def handleInt(i :Int) :Map[Int,Int] =
Try(divisor / i).fold({
case x : ArithmeticException => x.printStackTrace(); emptymap
case x : NumberFormatException => x.printStackTrace(); emptymap
}, answer => Map(divisor -> answer))
object FuncUtils {
#tailrec
def tryAll[T](funcs: (() => Any)*): Option[Any] = {
if (funcs.isEmpty) {
None
} else {
try {
Some(funcs.head())
} catch {
case _: Throwable => FuncUtils.tryAll(funcs.tail: _*)
}
}
}
}
Why? It appears to me that tryAll is self contained and the iteration can occur without referencing the call stack.
The error is not reproducible, you may try to provide more context.
Anyways, I would also recommend you to avoid Seq for tail-recursive algorithms (you should use a List instead), and try / catch blocks (use the Try Monad instead).
This is a rewrite of your code using that.
import scala.util.{Try, Success, Failure}
object FuncUtils {
def tryAll[T](funcs: (() => T)*): Option[T] = {
#annotation.tailrec
def loop(remaining: List[() => T]): Option[T] = remaining match {
case Nil => None
case x :: xs => Try(x()) match {
case Success(t) => Some(t)
case Failure(_) => loop(remaining = xs)
}
}
loop(remaining = funcs.toList)
}
}
Again, as jwvh said, yo really do not need recursion in this case.
object FuncUtils {
def tryAll[T](funcs: (() => T)*): Option[T] =
funcs.iterator.map(f => Try(f())).collectFirst { case Success(t) => t }
}
Ok the reason is because I am referring to the Singleton object that the method is contained in before calling the function.
FuncUtils.tryAll(funcs.tail: _*)
Should just be:
tryAll(funcs.tail: _*)
I guess scala can't figure out that its recursive when I reference the library.
I have a Future[T] and I want to map the result, on both success and failure.
Eg, something like
val future = ... // Future[T]
val mapped = future.mapAll {
case Success(a) => "OK"
case Failure(e) => "KO"
}
If I use map or flatmap, it will only map successes futures. If I use recover, it will only map failed futures. onComplete executes a callback but does not return a modified future. Transform will work, but takes 2 functions rather than a partial function, so is a bit uglier.
I know I could make a new Promise, and complete that with onComplete or onSuccess/onFailure, but I was hoping there was something I was missing that would allow me to do the above with a single PF.
Edit 2017-09-18: As of Scala 2.12, there is a transform method that takes a Try[T] => Try[S]. So you can write
val future = ... // Future[T]
val mapped = future.transform {
case Success(_) => Success("OK")
case Failure(_) => Success("KO")
}
For 2.11.x, the below still applies:
AFAIK, you can't do this directly with a single PF. And transform transforms Throwable => Throwable, so that won't help you either. The closest you can get out of the box:
val mapped: Future[String] = future.map(_ => "OK").recover{case _ => "KO"}
That said, implementing your mapAll is trivial:
implicit class RichFuture[T](f: Future[T]) {
def mapAll[U](pf: PartialFunction[Try[T], U]): Future[U] = {
val p = Promise[U]()
f.onComplete(r => p.complete(Try(pf(r))))
p.future
}
}
Since Scala 2.12 you can use transform to map both cases:
future.transform {
case Success(_) => Try("OK")
case Failure(_) => Try("KO")
}
You also have transformWith if you prefer to use a Future instead of a Try. Check the documentation for details.
In a first step, you could do something like:
import scala.util.{Try,Success,Failure}
val g = future.map( Success(_):Try[T] ).recover{
case t => Failure(t)
}.map {
case Success(s) => ...
case Failure(t) => ...
}
where T is the type of the future result. Then you can use an implicit conversion to add this structure the Future trait as a new method:
implicit class MyRichFuture[T]( fut: Future[T] ) {
def mapAll[U]( f: PartialFunction[Try[T],U] )( implicit ec: ExecutionContext ): Future[U] =
fut.map( Success(_):Try[T] ).recover{
case t => Failure(t)
}.map( f )
}
which implements the syntax your are looking for:
val future = Future{ 2 / 0 }
future.mapAll {
case Success(i) => i + 0.5
case Failure(_) => 0.0
}
Both map and flatMap variants:
implicit class FutureExtensions[T](f: Future[T]) {
def mapAll[Target](m: Try[T] => Target)(implicit ec: ExecutionContext): Future[Target] = {
val promise = Promise[Target]()
f.onComplete { r => promise success m(r) }(ec)
promise.future
}
def flatMapAll[Target](m: Try[T] => Future[Target])(implicit ec: ExecutionContext): Future[Target] = {
val promise = Promise[Target]()
f.onComplete { r => m(r).onComplete { z => promise complete z }(ec) }(ec)
promise.future
}
}
Is there a way to turn a Seq[Future[X]] into an Enumerator[X] ? The use case is that I want to get resources by crawling the web. This is going to return a Sequence of Futures, and I'd like to return an Enumerator that will push the futures in the order in which they are first finished on to the Iteratee.
It looks like Victor Klang's Future select gist could be used to do this - though it looks pretty inefficient.
Note: The Iteratees and Enumerator's in question are those given by the play framework version 2.x, ie with the following imports: import play.api.libs.iteratee._
Using Victor Klang's select method:
/**
* "Select" off the first future to be satisfied. Return this as a
* result, with the remainder of the Futures as a sequence.
*
* #param fs a scala.collection.Seq
*/
def select[A](fs: Seq[Future[A]])(implicit ec: ExecutionContext):
Future[(Try[A], Seq[Future[A]])] = {
#scala.annotation.tailrec
def stripe(p: Promise[(Try[A], Seq[Future[A]])],
heads: Seq[Future[A]],
elem: Future[A],
tail: Seq[Future[A]]): Future[(Try[A], Seq[Future[A]])] = {
elem onComplete { res => if (!p.isCompleted) p.trySuccess((res, heads ++ tail)) }
if (tail.isEmpty) p.future
else stripe(p, heads :+ elem, tail.head, tail.tail)
}
if (fs.isEmpty) Future.failed(new IllegalArgumentException("empty future list!"))
else stripe(Promise(), fs.genericBuilder[Future[A]].result, fs.head, fs.tail)
}
}
I can then get what I need with
Enumerator.unfoldM(initialSeqOfFutureAs){ seqOfFutureAs =>
if (seqOfFutureAs.isEmpty) {
Future(None)
} else {
FutureUtil.select(seqOfFutureAs).map {
case (t, seqFuture) => t.toOption.map {
a => (seqFuture, a)
}
}
}
}
A better, shorter and I think more efficient answer is:
def toEnumerator(seqFutureX: Seq[Future[X]]) = new Enumerator[X] {
def apply[A](i: Iteratee[X, A]): Future[Iteratee[X, A]] = {
Future.sequence(seqFutureX).flatMap { seqX: Seq[X] =>
seqX.foldLeft(Future.successful(i)) {
case (i, x) => i.flatMap(_.feed(Input.El(x)))
}
}
}
}
I do realise that the question is a bit old already, but based on Santhosh's answer and the built-in Enumterator.enumerate() implementation I came up with the following:
def enumerateM[E](traversable: TraversableOnce[Future[E]])(implicit ec: ExecutionContext): Enumerator[E] = {
val it = traversable.toIterator
Enumerator.generateM {
if (it.hasNext) {
val next: Future[E] = it.next()
next map {
e => Some(e)
}
} else {
Future.successful[Option[E]] {
None
}
}
}
}
Note that unlike the first Viktor-select-based-solution this one preserves the order, but you can still start off all computations asynchronously before. So, for example, you can do the following:
// For lack of a better name
def mapEachM[E, NE](eventuallyList: Future[List[E]])(f: E => Future[NE])(implicit ec: ExecutionContext): Enumerator[NE] =
Enumerator.flatten(
eventuallyList map { list =>
enumerateM(list map f)
}
)
This latter method was in fact what I was looking for when I stumbled on this thread. Hope it helps someone! :)
You could construct one using the Java Executor Completeion Service (JavaDoc). The idea is to use create a sequence of new futures, each using ExecutorCompletionService.take() to wait for the next result. Each future will start, when the previous future has its result.
But please b e aware, that this might be not that efficient, because a lot of synchronisation is happening behind the scenes. It might be more efficient, to use some parallel map reduce for calculation (e.g. using Scala's ParSeq) and let the Enumerator wait for the complete result.
WARNING: Not compiled before answering
What about something like this:
def toEnumerator(seqFutureX: Seq[Future[X]]) = new Enumerator[X] {
def apply[A](i: Iteratee[X, A]): Future[Iteratee[X, A]] =
Future.fold(seqFutureX)(i){ case (i, x) => i.flatMap(_.feed(Input.El(x)))) }
}
Here is something I found handy,
def unfold[A,B](xs:Seq[A])(proc:A => Future[B])(implicit errorHandler:Throwable => B):Enumerator[B] = {
Enumerator.unfoldM (xs) { xs =>
if (xs.isEmpty) Future(None)
else proc(xs.head) map (b => Some(xs.tail,b)) recover {
case e => Some((xs.tail,errorHandler(e)))
}
}
}
def unfold[A,B](fxs:Future[Seq[A]])(proc:A => Future[B]) (implicit errorHandler1:Throwable => Seq[A], errorHandler:Throwable => B) :Enumerator[B] = {
(unfold(Seq(fxs))(fxs => fxs)(errorHandler1)).flatMap(unfold(_)(proc)(errorHandler))
}
def unfoldFutures[A,B](xsfxs:Seq[Future[Seq[A]]])(proc:A => Future[B]) (implicit errorHandler1:Throwable => Seq[A], errorHandler:Throwable => B) :Enumerator[B] = {
xsfxs.map(unfold(_)(proc)).reduceLeft((a,b) => a.andThen(b))
}
I would like to propose the use of a Broadcast
def seqToEnumerator[A](futuresA: Seq[Future[A]])(defaultValue: A, errorHandler: Throwable => A): Enumerator[A] ={
val (enumerator, channel) = Concurrent.broadcast[A]
futuresA.foreach(f => f.onComplete({
case Success(Some(a: A)) => channel.push(a)
case Success(None) => channel.push(defaultValue)
case Failure(exception) => channel.push(errorHandler(exception))
}))
enumerator
}
I added errorHandling and defaultValues but you can skip those by using onSuccess or onFailure, instead of onComplete