According to Erik Meijer, as functional programmers, we all know that instead of recursion, we should use fold. How do you convert the following to use fold? I can see one way with return, but return should also be avoided in fp. Thanks!
def tryOld(string: String, original: Exception, zomOldList: List[String => Double]): Double = {
zomOldList match {
case Nil =>
throw original
case head :: tail =>
try {
head(string)
} catch {
case ex: Exception =>
tryOld(string, original, tail)
}
}
}
You can implement this with foldRight taking advantage of functions being values:
import util.control.NonFatal
def tryOld(string: String, original: Exception, zomOldList: List[String ⇒ Double]): Double = {
val unhandled: String ⇒ Double = _ ⇒ throw original
zomOldList.foldRight(unhandled) { (f, z) ⇒
x ⇒ try { f(x) } catch { case NonFatal(_) ⇒ z(x) }
}(string)
}
Note we use NonFatal here to avoid catching exceptions that we shouldn't be catching. You can write this in a more elegant way by not using exceptions directly.
You cannot implement this with a fold. A fold loops over every element of a collection, whereas tryOld will sometimes terminate early. You could take advantage of Stream's laziness and implement it in terms of collectFirst and Try:
import scala.util.Try
def tryOld(string: String, original: Exception, zomOldList: List[String => Double]): Double =
zomOldList.toStream.map(x => Try(x(string))) collectFirst {
case Success(x) => x
} getOrElse (throw original)
but your original recursive implementation is clearer and more performant.
EDIT:
If Scala had a foldRight with the same laziness properties as Haskell's foldr, then this could be defined in terms of foldRight:
implicit class GiveStreamAWorkingFoldRight[A](val s: Stream[A]) extends AnyVal {
def lazyFoldRight[B](z: => B)(f: (A, () => B) => B): B =
if (s.isEmpty) z else f(s.head, () => s.tail.lazyFoldRight(z)(f))
}
def tryOld(string: String, original: Exception, zomOldList: List[String => Double]): Double =
zomOldList.toStream.lazyFoldRight(throw original) { (a, b: () => Double) =>
try {
a(string)
} catch {
case ex: Exception => b()
}
}
However, Scala's lack of true tail-call optimization means that each call to b will introduce a new stack frame, potentially leading to a stack overflow.
Here's a solution with foldLeft. It is lengthy since I first wrote a generic function which is called by tryOldString
def tryOld[In, Error, Out](
in: In,
original: Error,
zomOldList: List[In => Either[Error, Out]]
): Either[Error, Out] = {
val seed: Either[Error, Out] = Left(original)
zomOldList.foldLeft(seed) {
case (prev, f) =>
// stores first match without return
if (seed != prev) {
prev
} else {
f(in).fold(
fa =>
prev,
fb =>
Right(fb)
)
}
}
}
def tryOutString(string: String, original: Exception, zomOldList: List[String => Double]): Double = {
val zomFunctions: List[String => Either[Exception, Double]] = zomOldList.map {
f =>
s: String =>
try {
Right(f(s))
} catch {
case e: Exception =>
Left(e)
}
}
tryOld(string, original, zomFunctions).fold(
bad => throw original,
good => good
)
}
Related
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 want to get value from function that passed as parameter and returns Option[Int], after that if I have None throw an exception and in any other case return value
I tried to do like this:
def foo[T](f: T => Option[Int]) = {
def helper(x: T) = f(x)
val res = helper _
res match {
case None => throw new Exception()
case Some(z) => z
}
I call it like this:
val test = foo[String](myFunction(_))
test("Some string")
I have compilation error with mismatched types in match section (Some[A] passed - [T] => Option[Int] required)
As I understood res variable is reference to the function and I cannot match it with optional either call get\gerOrElse methods.
Moreover I probably just dont get how the underscore works and doing something really wrong, I'm using it here to pass a something as parameter to function f, can you explain me where I made a mistake?
helper is a method taking a T and returning an Option[Int].
res is a function T => Option[Int].
Difference between method and function in Scala
You can't match a function T => Option[Int] with None or Some(z).
You should have an Option[Int] (for example the function applied to some T) to make such matching.
Probably you would like to have
def foo[T](f: T => Option[Int]) = {
def helper(x: T) = f(x)
val res = helper _
(t: T) => res(t) match {
case None => throw new Exception()
case Some(z) => z
}
}
or just
def foo[T](f: T => Option[Int]): T => Int = {
t => f(t) match {
case None => throw new Exception()
case Some(z) => z
}
}
or
def foo[T](f: T => Option[Int]): T => Int =
t => f(t).getOrElse(throw new Exception())
In scalaz 7.2.6, I want to implement sequence on Disjunction, such that if there is one or more lefts, it returns a list of those, instead of taking only the first one (as in Disjunction.sequenceU):
import scalaz._, Scalaz._
List(1.right, 2.right, 3.right).sequence
res1: \/-(List(1, 2, 3))
List(1.right, "error2".left, "error3".left).sequence
res2: -\/(List(error2, error3))
I've implemented it as follows and it works, but it looks ugly. Is there a getRight method (such as in scala Either class, Right[String, Int](3).right.get)? And how to improve this code?
implicit class RichSequence[L, R](val l: List[\/[L, R]]) {
def getLeft(v: \/[L, R]):L = v match { case -\/(x) => x }
def getRight(v: \/[L, R]):R = v match { case \/-(x) => x }
def sequence: \/[List[L], List[R]] =
if (l.forall(_.isRight)) {
l.map(e => getRight(e)).right
} else {
l.filter(_.isLeft).map(e => getLeft(e)).left
}
}
Playing around I've implemented a recursive function for that, but the best option would be to use separate:
implicit class RichSequence[L, R](val l: List[\/[L, R]]) {
def sequence: \/[List[L], List[R]] = {
def seqLoop(left: List[L], right: List[R], list: List[\/[L, R]]): \/[List[L], List[R]] =
list match {
case (h :: t) =>
h match {
case -\/(e) => seqLoop(left :+ e, right, t)
case \/-(s) => seqLoop(left, right :+ s, t)
}
case Nil =>
if(left.isEmpty) \/-(right)
else -\/(left)
}
seqLoop(List(), List(), l)
}
def sequenceSeparate: \/[List[L], List[R]] = {
val (left, right) = l.separate[\/[L, R], L, R]
if(left.isEmpty) \/-(right)
else -\/(left)
}
}
The first one just collects results and at the end decide what to do with those, the second its basically the same with the exception that the recursive function is much simpler, I didn't think about performance here, I've used :+, if you care use prepend or some other collection.
You may also want to take a look at Validation and ValidationNEL which unlike Disjunction accumulate failures.
Given a block that catches more than one exception is it possible to handle multiple exceptions without putting the desired value in every case block? e.g. it would be nice if something like this worked:
val foo: Int = try {
//do stuff that results in an Int
} catch {
case e: SomeException => //do something if this gets thrown
case e: SomeOtherException => //do something different if this gets thrown
0
}
But that results in a compile error (type mismatch; found : Unit required: Int). I could put the default in each throwable case e: SomeException => {/*do something if this gets thrown*/; 0} - but that just seems like code smell so I'm hoping there is a more elegant solution.
You could simply wrap the exception handling:
val foo: Int = try {
//do stuff that results in an Int
17
} catch { case t: Throwable => t match {
case e: SomeException => //do something if this gets thrown
case e: SomeOtherException => //do something different if this gets thrown
}
42
}
You can take advantage of partial functions to do your error handling using the built in Try
val foo: Int ={
val value = Try{
//stuff
}
unwrap(0, value){
case x: SomeException => doStuff()
case x: OtherExcetion => doMoreStuff()
}
}
def unwrap[A](ret: A, value: Try[A])(f: Failure[A] => Unit): A = value match{
case Success(x) => x
case x: Failure => f(x); ret
}
and voila, you've handled it quite well.
The catch keyword expects a PartialFunction, which can easily be chained with andThen:
scala> val pf1: PartialFunction[Throwable, Unit] = { case _: IllegalArgumentException => println("pf1") }
pf1: PartialFunction[Throwable,Unit] = <function1>
scala> val pf2: PartialFunction[Unit, Int] = { case _ => println("pf2"); 0}
pf2: PartialFunction[Unit,Int] = <function1>
scala> try throw new IllegalArgumentException catch pf1 andThen pf2
pf1
pf2
res0: Int = 0
scala> try throw new NoSuchElementException catch pf1 andThen pf2
java.util.NoSuchElementException
The second PartialFunction is only executed when the first one matched its argument, which can be a problem when you want to catch other exceptions (that also should not return the default value). But for this case, there is orElse:
scala> val pf3: PartialFunction[Throwable, Int] = { case _ => println("pf3"); 1}
pf3: PartialFunction[Throwable,Int] = <function1>
scala> try throw new NoSuchElementException catch pf1 andThen pf2 orElse pf3
pf3
res2: Int = 1
You can use the Try object to wrap your possibly failing code, and then compose the outcome like this
val foo: Int = (Try {
//do stuff that results in an Int
} recover {
//here we handle the recovering
handleFail andThen defaultInt
}).get
val handleFail: PartialFunction[Throwable, Unit] = {
case e: SomeException => //do something if this gets thrown
case e: SomeOtherException => //do something different if this gets thrown
val defaultInt: PartialFunction[Unit, Int] = { case _ => 0 }
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