Flatten Scala Try
Is there a simple way to flatten a collection of try's to give either a success of the try values, or just the failure?
For example:
def map(l:List[Int]) = l map {
case 4 => Failure(new Exception("failed"))
case i => Success(i)
}
val l1 = List(1,2,3,4,5,6)
val result1 = something(map(l1))
result1: Failure(Exception("failed"))
val l2 = List(1,2,3,5,6)
val result2 = something(map(l2))
result2: Try(List(1,2,3,5,6))
And can how would you handle multiple Failures in the collection?
scala try-catch scala-2.10
add a comment |
Is there a simple way to flatten a collection of try's to give either a success of the try values, or just the failure?
For example:
def map(l:List[Int]) = l map {
case 4 => Failure(new Exception("failed"))
case i => Success(i)
}
val l1 = List(1,2,3,4,5,6)
val result1 = something(map(l1))
result1: Failure(Exception("failed"))
val l2 = List(1,2,3,5,6)
val result2 = something(map(l2))
result2: Try(List(1,2,3,5,6))
And can how would you handle multiple Failures in the collection?
scala try-catch scala-2.10
3
Please say how your result should look like.List(1, 2, 3, Exception, 5, 7)
?
– Malte Schwerhoff
Mar 19 '13 at 9:41
1
Scalaz would call this operationsequence
, but it's sadly missing from the standard library.
– Impredicative
Mar 19 '13 at 10:29
add a comment |
Is there a simple way to flatten a collection of try's to give either a success of the try values, or just the failure?
For example:
def map(l:List[Int]) = l map {
case 4 => Failure(new Exception("failed"))
case i => Success(i)
}
val l1 = List(1,2,3,4,5,6)
val result1 = something(map(l1))
result1: Failure(Exception("failed"))
val l2 = List(1,2,3,5,6)
val result2 = something(map(l2))
result2: Try(List(1,2,3,5,6))
And can how would you handle multiple Failures in the collection?
scala try-catch scala-2.10
Is there a simple way to flatten a collection of try's to give either a success of the try values, or just the failure?
For example:
def map(l:List[Int]) = l map {
case 4 => Failure(new Exception("failed"))
case i => Success(i)
}
val l1 = List(1,2,3,4,5,6)
val result1 = something(map(l1))
result1: Failure(Exception("failed"))
val l2 = List(1,2,3,5,6)
val result2 = something(map(l2))
result2: Try(List(1,2,3,5,6))
And can how would you handle multiple Failures in the collection?
scala try-catch scala-2.10
scala try-catch scala-2.10
edited Mar 19 '13 at 10:07
J Pullar
asked Mar 19 '13 at 9:29
J PullarJ Pullar
98811025
98811025
3
Please say how your result should look like.List(1, 2, 3, Exception, 5, 7)
?
– Malte Schwerhoff
Mar 19 '13 at 9:41
1
Scalaz would call this operationsequence
, but it's sadly missing from the standard library.
– Impredicative
Mar 19 '13 at 10:29
add a comment |
3
Please say how your result should look like.List(1, 2, 3, Exception, 5, 7)
?
– Malte Schwerhoff
Mar 19 '13 at 9:41
1
Scalaz would call this operationsequence
, but it's sadly missing from the standard library.
– Impredicative
Mar 19 '13 at 10:29
3
3
Please say how your result should look like.
List(1, 2, 3, Exception, 5, 7)
?– Malte Schwerhoff
Mar 19 '13 at 9:41
Please say how your result should look like.
List(1, 2, 3, Exception, 5, 7)
?– Malte Schwerhoff
Mar 19 '13 at 9:41
1
1
Scalaz would call this operation
sequence
, but it's sadly missing from the standard library.– Impredicative
Mar 19 '13 at 10:29
Scalaz would call this operation
sequence
, but it's sadly missing from the standard library.– Impredicative
Mar 19 '13 at 10:29
add a comment |
7 Answers
7
active
oldest
votes
Maybe not as simple as you hoped for, but this works:
def flatten[T](xs: Seq[Try[T]]): Try[Seq[T]] = {
val (ss: Seq[Success[T]]@unchecked, fs: Seq[Failure[T]]@unchecked) =
xs.partition(_.isSuccess)
if (fs.isEmpty) Success(ss map (_.get))
else Failure[Seq[T]](fs(0).exception) // Only keep the first failure
}
val xs = List(1,2,3,4,5,6)
val ys = List(1,2,3,5,6)
println(flatten(map(xs))) // Failure(java.lang.Exception: failed)
println(flatten(map(ys))) // Success(List(1, 2, 3, 5, 6))
Note that the use of partition
is not as type safe as it gets, as witnessed by the @unchecked
annotations. In that respect, a foldLeft
that accumulates two sequences Seq[Success[T]]
and Seq[Failure[T]]
would be better.
If you wanted to keep all failures, you can use this:
def flatten2[T](xs: Seq[Try[T]]): Either[Seq[T], Seq[Throwable]] = {
val (ss: Seq[Success[T]]@unchecked, fs: Seq[Failure[T]]@unchecked) =
xs.partition(_.isSuccess)
if (fs.isEmpty) Left(ss map (_.get))
else Right(fs map (_.exception))
}
val zs = List(1,4,2,3,4,5,6)
println(flatten2(map(xs))) // Right(List(java.lang.Exception: failed))
println(flatten2(map(ys))) // Left(List(1, 2, 3, 5, 6))
println(flatten2(map(zs))) // Right(List(java.lang.Exception: failed,
// java.lang.Exception: failed))
+1 " In that respect, a foldLeft that accumulates two sequences Seq[Success[T]] and Seq[Failure[T]] would be better. " Yes ! There is so many validation or failures types in the scala ecosystem (Option, Either, Try, scalaz.Disjunction, scalaz.Validation,...), and still I couldn't find any such double seq fold exemples among the public methods and common patterns.
– rloth
Feb 2 '18 at 10:41
add a comment |
This is pretty close to minimal for fail-first operation:
def something[A](xs: Seq[Try[A]]) =
Try(xs.map(_.get))
(to the point where you shouldn't bother creating a method; just use Try
). If you want all the failures, a method is reasonable; I'd use an Either
:
def something[A](xs: Seq[Try[A]]) =
Try(Right(xs.map(_.get))).
getOrElse(Left(xs.collect{ case Failure(t) => t }))
Nice! (Although it re-throws the exception, if any) How would you extend it such that all exceptions are kept?
– Malte Schwerhoff
Mar 19 '13 at 13:21
@mhs - If failure is uncommon or performance is not critical, you want the re-throw as it's the simplest way to deal with the problem. The exception's stack trace has already been generated, so the throw/catch itself isn't too expensive. If I wanted to keep all exceptions I'd pack them in anEither
instead, e.g. as in my edit.
– Rex Kerr
Mar 19 '13 at 15:31
add a comment |
A little less verbose, and more type safe:
def sequence[T](xs : Seq[Try[T]]) : Try[Seq[T]] = (Try(Seq[T]()) /: xs) {
(a, b) => a flatMap (c => b map (d => c :+ d))
}
Results:
sequence(l1)
res8: scala.util.Try[Seq[Int]] = Failure(java.lang.Exception: failed)
sequence(l2)
res9: scala.util.Try[Seq[Int]] = Success(List(1, 2, 3, 5, 6))
It looks nice, though is there not going to be quite a performance hit with the append operation?
– J Pullar
Mar 19 '13 at 11:38
1
Fair point - I'd forgotten that the defaultSeq
is aList
. Add reverse/use a vector at your discretion!
– Impredicative
Mar 19 '13 at 14:07
Nice, I hadnt seen that foldLeft shortcut before/:
– Stephen
May 22 '17 at 6:06
add a comment |
As an addition to Impredicative's answer and comment, if you have both scalaz-seven and scalaz-contrib/scala210 in your dependencies:
> scala210/console
[warn] Credentials file /home/folone/.ivy2/.credentials does not exist
[info] Starting scala interpreter...
[info]
Welcome to Scala version 2.10.0 (OpenJDK 64-Bit Server VM, Java 1.7.0_17).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import scala.util._
import scala.util._
scala> def map(l:List[Int]): List[Try[Int]] = l map {
| case 4 => Failure(new Exception("failed"))
| case i => Success(i)
| }
map: (l: List[Int])List[scala.util.Try[Int]]
scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._
scala> import scalaz.contrib.std.utilTry._
import scalaz.contrib.std.utilTry._
scala> val l1 = List(1,2,3,4,5,6)
l1: List[Int] = List(1, 2, 3, 4, 5, 6)
scala> map(l1).sequence
res2: scala.util.Try[List[Int]] = Failure(java.lang.Exception: failed)
scala> val l2 = List(1,2,3,5,6)
l2: List[Int] = List(1, 2, 3, 5, 6)
scala> map(l2).sequence
res3: scala.util.Try[List[Int]] = Success(List(1, 2, 3, 5, 6))
You need scalaz to get an Applicative
instance for the List
(hidden in the MonadPlus
instance), to get the sequence
method. You need scalaz-contrib for the Traverse
instance of Try
, which is required by the sequence
's type signature.
Try
lives outside of scalaz, since it only appeared in scala 2.10, and scalaz aims to cross-compile to earlier versions).
add a comment |
Have a look on the liftweb Box monad. With the help of the tryo
constructor function, it gives you exactly the abstraction you are looking for.
With tryo
you can lift a function into a Box
. The box then either contains the result from the function or it contains an error. You can then access the box with the usual monadic helper functions (flatMap, filter, etc.), without bothering if the box contains an error or the result form the function.
Example:
import net.liftweb.util.Helpers.tryo
List("1", "2", "not_a_number") map (x => tryo(x.toInt)) map (_ map (_ + 1 ))
Results to
List[net.liftweb.common.Box[Int]] =
List(
Full(2),
Full(3),
Failure(For input string: "not_a_number",Full(java.lang.NumberFormatException: For input string: "not_a_number"),Empty)
)
You can skip the erroneous values with flatMap
List("1", "2", "not_a_number") map (x => tryo(x.toInt)) flatMap (_ map (_ + 1 ))
Results
List[Int] = List(2, 3)
There are multiple other helper methods, e.g. for combining boxes (while chaining error messages). You can find a good overview here: Box Cheat Sheet for Lift
You can use it on its own, no need to use the whole lift framework. For the examples above I used the follwing sbt script:
scalaVersion := "2.9.1"
libraryDependencies += "net.liftweb" %% "lift-common" % "2.5-RC2"
libraryDependencies += "net.liftweb" %% "lift-util" % "2.5-RC2"
add a comment |
These are my 2cents:
def sequence[A, M[_] <: TraversableOnce[_]](in: M[Try[A]])
(implicit cbf:CanBuildFrom[M[Try[A]], A, M[A]]): Try[M[A]] = {
in.foldLeft(Try(cbf(in))) {
(txs, tx) =>
for {
xs <- txs
x <- tx.asInstanceOf[Try[A]]
} yield {
xs += x
}
}.map(_.result())
}
add a comment |
Starting Scala 2.13
, most collections are provided with a partitionWith
method which partitions elements based on a function which returns either Right
or Left
.
In our case we can call partitionWith
with a function that transforms our Try
s into Either
s (Try::toEither
) in order to partition Success
es as Right
s and Failure
s as Left
s.
Then it's a simple matter of matching the resulting partitioned tuple of lefts and rights based on whether or not there are lefts:
tries.partitionWith(_.toEither) match {
case (Nil, rights) => Success(rights)
case (firstLeft :: _, _) => Failure(firstLeft)
}
// * val tries = List(Success(10), Success(20), Success(30))
// => Try[List[Int]] = Success(List(10, 20, 30))
// * val tries = List(Success(10), Success(20), Failure(new Exception("error1")))
// => Try[List[Int]] = Failure(java.lang.Exception: error1)
Details of the intermediate partitionWith
step:
List(Success(10), Success(20), Failure(new Exception("error1"))).partitionWith(_.toEither)
// => (List[Throwable], List[Int]) = (List(java.lang.Exception: error1), List(10, 20))
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f15495678%2fflatten-scala-try%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
7 Answers
7
active
oldest
votes
7 Answers
7
active
oldest
votes
active
oldest
votes
active
oldest
votes
Maybe not as simple as you hoped for, but this works:
def flatten[T](xs: Seq[Try[T]]): Try[Seq[T]] = {
val (ss: Seq[Success[T]]@unchecked, fs: Seq[Failure[T]]@unchecked) =
xs.partition(_.isSuccess)
if (fs.isEmpty) Success(ss map (_.get))
else Failure[Seq[T]](fs(0).exception) // Only keep the first failure
}
val xs = List(1,2,3,4,5,6)
val ys = List(1,2,3,5,6)
println(flatten(map(xs))) // Failure(java.lang.Exception: failed)
println(flatten(map(ys))) // Success(List(1, 2, 3, 5, 6))
Note that the use of partition
is not as type safe as it gets, as witnessed by the @unchecked
annotations. In that respect, a foldLeft
that accumulates two sequences Seq[Success[T]]
and Seq[Failure[T]]
would be better.
If you wanted to keep all failures, you can use this:
def flatten2[T](xs: Seq[Try[T]]): Either[Seq[T], Seq[Throwable]] = {
val (ss: Seq[Success[T]]@unchecked, fs: Seq[Failure[T]]@unchecked) =
xs.partition(_.isSuccess)
if (fs.isEmpty) Left(ss map (_.get))
else Right(fs map (_.exception))
}
val zs = List(1,4,2,3,4,5,6)
println(flatten2(map(xs))) // Right(List(java.lang.Exception: failed))
println(flatten2(map(ys))) // Left(List(1, 2, 3, 5, 6))
println(flatten2(map(zs))) // Right(List(java.lang.Exception: failed,
// java.lang.Exception: failed))
+1 " In that respect, a foldLeft that accumulates two sequences Seq[Success[T]] and Seq[Failure[T]] would be better. " Yes ! There is so many validation or failures types in the scala ecosystem (Option, Either, Try, scalaz.Disjunction, scalaz.Validation,...), and still I couldn't find any such double seq fold exemples among the public methods and common patterns.
– rloth
Feb 2 '18 at 10:41
add a comment |
Maybe not as simple as you hoped for, but this works:
def flatten[T](xs: Seq[Try[T]]): Try[Seq[T]] = {
val (ss: Seq[Success[T]]@unchecked, fs: Seq[Failure[T]]@unchecked) =
xs.partition(_.isSuccess)
if (fs.isEmpty) Success(ss map (_.get))
else Failure[Seq[T]](fs(0).exception) // Only keep the first failure
}
val xs = List(1,2,3,4,5,6)
val ys = List(1,2,3,5,6)
println(flatten(map(xs))) // Failure(java.lang.Exception: failed)
println(flatten(map(ys))) // Success(List(1, 2, 3, 5, 6))
Note that the use of partition
is not as type safe as it gets, as witnessed by the @unchecked
annotations. In that respect, a foldLeft
that accumulates two sequences Seq[Success[T]]
and Seq[Failure[T]]
would be better.
If you wanted to keep all failures, you can use this:
def flatten2[T](xs: Seq[Try[T]]): Either[Seq[T], Seq[Throwable]] = {
val (ss: Seq[Success[T]]@unchecked, fs: Seq[Failure[T]]@unchecked) =
xs.partition(_.isSuccess)
if (fs.isEmpty) Left(ss map (_.get))
else Right(fs map (_.exception))
}
val zs = List(1,4,2,3,4,5,6)
println(flatten2(map(xs))) // Right(List(java.lang.Exception: failed))
println(flatten2(map(ys))) // Left(List(1, 2, 3, 5, 6))
println(flatten2(map(zs))) // Right(List(java.lang.Exception: failed,
// java.lang.Exception: failed))
+1 " In that respect, a foldLeft that accumulates two sequences Seq[Success[T]] and Seq[Failure[T]] would be better. " Yes ! There is so many validation or failures types in the scala ecosystem (Option, Either, Try, scalaz.Disjunction, scalaz.Validation,...), and still I couldn't find any such double seq fold exemples among the public methods and common patterns.
– rloth
Feb 2 '18 at 10:41
add a comment |
Maybe not as simple as you hoped for, but this works:
def flatten[T](xs: Seq[Try[T]]): Try[Seq[T]] = {
val (ss: Seq[Success[T]]@unchecked, fs: Seq[Failure[T]]@unchecked) =
xs.partition(_.isSuccess)
if (fs.isEmpty) Success(ss map (_.get))
else Failure[Seq[T]](fs(0).exception) // Only keep the first failure
}
val xs = List(1,2,3,4,5,6)
val ys = List(1,2,3,5,6)
println(flatten(map(xs))) // Failure(java.lang.Exception: failed)
println(flatten(map(ys))) // Success(List(1, 2, 3, 5, 6))
Note that the use of partition
is not as type safe as it gets, as witnessed by the @unchecked
annotations. In that respect, a foldLeft
that accumulates two sequences Seq[Success[T]]
and Seq[Failure[T]]
would be better.
If you wanted to keep all failures, you can use this:
def flatten2[T](xs: Seq[Try[T]]): Either[Seq[T], Seq[Throwable]] = {
val (ss: Seq[Success[T]]@unchecked, fs: Seq[Failure[T]]@unchecked) =
xs.partition(_.isSuccess)
if (fs.isEmpty) Left(ss map (_.get))
else Right(fs map (_.exception))
}
val zs = List(1,4,2,3,4,5,6)
println(flatten2(map(xs))) // Right(List(java.lang.Exception: failed))
println(flatten2(map(ys))) // Left(List(1, 2, 3, 5, 6))
println(flatten2(map(zs))) // Right(List(java.lang.Exception: failed,
// java.lang.Exception: failed))
Maybe not as simple as you hoped for, but this works:
def flatten[T](xs: Seq[Try[T]]): Try[Seq[T]] = {
val (ss: Seq[Success[T]]@unchecked, fs: Seq[Failure[T]]@unchecked) =
xs.partition(_.isSuccess)
if (fs.isEmpty) Success(ss map (_.get))
else Failure[Seq[T]](fs(0).exception) // Only keep the first failure
}
val xs = List(1,2,3,4,5,6)
val ys = List(1,2,3,5,6)
println(flatten(map(xs))) // Failure(java.lang.Exception: failed)
println(flatten(map(ys))) // Success(List(1, 2, 3, 5, 6))
Note that the use of partition
is not as type safe as it gets, as witnessed by the @unchecked
annotations. In that respect, a foldLeft
that accumulates two sequences Seq[Success[T]]
and Seq[Failure[T]]
would be better.
If you wanted to keep all failures, you can use this:
def flatten2[T](xs: Seq[Try[T]]): Either[Seq[T], Seq[Throwable]] = {
val (ss: Seq[Success[T]]@unchecked, fs: Seq[Failure[T]]@unchecked) =
xs.partition(_.isSuccess)
if (fs.isEmpty) Left(ss map (_.get))
else Right(fs map (_.exception))
}
val zs = List(1,4,2,3,4,5,6)
println(flatten2(map(xs))) // Right(List(java.lang.Exception: failed))
println(flatten2(map(ys))) // Left(List(1, 2, 3, 5, 6))
println(flatten2(map(zs))) // Right(List(java.lang.Exception: failed,
// java.lang.Exception: failed))
answered Mar 19 '13 at 10:29
Malte SchwerhoffMalte Schwerhoff
9,30943060
9,30943060
+1 " In that respect, a foldLeft that accumulates two sequences Seq[Success[T]] and Seq[Failure[T]] would be better. " Yes ! There is so many validation or failures types in the scala ecosystem (Option, Either, Try, scalaz.Disjunction, scalaz.Validation,...), and still I couldn't find any such double seq fold exemples among the public methods and common patterns.
– rloth
Feb 2 '18 at 10:41
add a comment |
+1 " In that respect, a foldLeft that accumulates two sequences Seq[Success[T]] and Seq[Failure[T]] would be better. " Yes ! There is so many validation or failures types in the scala ecosystem (Option, Either, Try, scalaz.Disjunction, scalaz.Validation,...), and still I couldn't find any such double seq fold exemples among the public methods and common patterns.
– rloth
Feb 2 '18 at 10:41
+1 " In that respect, a foldLeft that accumulates two sequences Seq[Success[T]] and Seq[Failure[T]] would be better. " Yes ! There is so many validation or failures types in the scala ecosystem (Option, Either, Try, scalaz.Disjunction, scalaz.Validation,...), and still I couldn't find any such double seq fold exemples among the public methods and common patterns.
– rloth
Feb 2 '18 at 10:41
+1 " In that respect, a foldLeft that accumulates two sequences Seq[Success[T]] and Seq[Failure[T]] would be better. " Yes ! There is so many validation or failures types in the scala ecosystem (Option, Either, Try, scalaz.Disjunction, scalaz.Validation,...), and still I couldn't find any such double seq fold exemples among the public methods and common patterns.
– rloth
Feb 2 '18 at 10:41
add a comment |
This is pretty close to minimal for fail-first operation:
def something[A](xs: Seq[Try[A]]) =
Try(xs.map(_.get))
(to the point where you shouldn't bother creating a method; just use Try
). If you want all the failures, a method is reasonable; I'd use an Either
:
def something[A](xs: Seq[Try[A]]) =
Try(Right(xs.map(_.get))).
getOrElse(Left(xs.collect{ case Failure(t) => t }))
Nice! (Although it re-throws the exception, if any) How would you extend it such that all exceptions are kept?
– Malte Schwerhoff
Mar 19 '13 at 13:21
@mhs - If failure is uncommon or performance is not critical, you want the re-throw as it's the simplest way to deal with the problem. The exception's stack trace has already been generated, so the throw/catch itself isn't too expensive. If I wanted to keep all exceptions I'd pack them in anEither
instead, e.g. as in my edit.
– Rex Kerr
Mar 19 '13 at 15:31
add a comment |
This is pretty close to minimal for fail-first operation:
def something[A](xs: Seq[Try[A]]) =
Try(xs.map(_.get))
(to the point where you shouldn't bother creating a method; just use Try
). If you want all the failures, a method is reasonable; I'd use an Either
:
def something[A](xs: Seq[Try[A]]) =
Try(Right(xs.map(_.get))).
getOrElse(Left(xs.collect{ case Failure(t) => t }))
Nice! (Although it re-throws the exception, if any) How would you extend it such that all exceptions are kept?
– Malte Schwerhoff
Mar 19 '13 at 13:21
@mhs - If failure is uncommon or performance is not critical, you want the re-throw as it's the simplest way to deal with the problem. The exception's stack trace has already been generated, so the throw/catch itself isn't too expensive. If I wanted to keep all exceptions I'd pack them in anEither
instead, e.g. as in my edit.
– Rex Kerr
Mar 19 '13 at 15:31
add a comment |
This is pretty close to minimal for fail-first operation:
def something[A](xs: Seq[Try[A]]) =
Try(xs.map(_.get))
(to the point where you shouldn't bother creating a method; just use Try
). If you want all the failures, a method is reasonable; I'd use an Either
:
def something[A](xs: Seq[Try[A]]) =
Try(Right(xs.map(_.get))).
getOrElse(Left(xs.collect{ case Failure(t) => t }))
This is pretty close to minimal for fail-first operation:
def something[A](xs: Seq[Try[A]]) =
Try(xs.map(_.get))
(to the point where you shouldn't bother creating a method; just use Try
). If you want all the failures, a method is reasonable; I'd use an Either
:
def something[A](xs: Seq[Try[A]]) =
Try(Right(xs.map(_.get))).
getOrElse(Left(xs.collect{ case Failure(t) => t }))
edited Mar 19 '13 at 15:34
answered Mar 19 '13 at 13:00
Rex KerrRex Kerr
150k20280379
150k20280379
Nice! (Although it re-throws the exception, if any) How would you extend it such that all exceptions are kept?
– Malte Schwerhoff
Mar 19 '13 at 13:21
@mhs - If failure is uncommon or performance is not critical, you want the re-throw as it's the simplest way to deal with the problem. The exception's stack trace has already been generated, so the throw/catch itself isn't too expensive. If I wanted to keep all exceptions I'd pack them in anEither
instead, e.g. as in my edit.
– Rex Kerr
Mar 19 '13 at 15:31
add a comment |
Nice! (Although it re-throws the exception, if any) How would you extend it such that all exceptions are kept?
– Malte Schwerhoff
Mar 19 '13 at 13:21
@mhs - If failure is uncommon or performance is not critical, you want the re-throw as it's the simplest way to deal with the problem. The exception's stack trace has already been generated, so the throw/catch itself isn't too expensive. If I wanted to keep all exceptions I'd pack them in anEither
instead, e.g. as in my edit.
– Rex Kerr
Mar 19 '13 at 15:31
Nice! (Although it re-throws the exception, if any) How would you extend it such that all exceptions are kept?
– Malte Schwerhoff
Mar 19 '13 at 13:21
Nice! (Although it re-throws the exception, if any) How would you extend it such that all exceptions are kept?
– Malte Schwerhoff
Mar 19 '13 at 13:21
@mhs - If failure is uncommon or performance is not critical, you want the re-throw as it's the simplest way to deal with the problem. The exception's stack trace has already been generated, so the throw/catch itself isn't too expensive. If I wanted to keep all exceptions I'd pack them in an
Either
instead, e.g. as in my edit.– Rex Kerr
Mar 19 '13 at 15:31
@mhs - If failure is uncommon or performance is not critical, you want the re-throw as it's the simplest way to deal with the problem. The exception's stack trace has already been generated, so the throw/catch itself isn't too expensive. If I wanted to keep all exceptions I'd pack them in an
Either
instead, e.g. as in my edit.– Rex Kerr
Mar 19 '13 at 15:31
add a comment |
A little less verbose, and more type safe:
def sequence[T](xs : Seq[Try[T]]) : Try[Seq[T]] = (Try(Seq[T]()) /: xs) {
(a, b) => a flatMap (c => b map (d => c :+ d))
}
Results:
sequence(l1)
res8: scala.util.Try[Seq[Int]] = Failure(java.lang.Exception: failed)
sequence(l2)
res9: scala.util.Try[Seq[Int]] = Success(List(1, 2, 3, 5, 6))
It looks nice, though is there not going to be quite a performance hit with the append operation?
– J Pullar
Mar 19 '13 at 11:38
1
Fair point - I'd forgotten that the defaultSeq
is aList
. Add reverse/use a vector at your discretion!
– Impredicative
Mar 19 '13 at 14:07
Nice, I hadnt seen that foldLeft shortcut before/:
– Stephen
May 22 '17 at 6:06
add a comment |
A little less verbose, and more type safe:
def sequence[T](xs : Seq[Try[T]]) : Try[Seq[T]] = (Try(Seq[T]()) /: xs) {
(a, b) => a flatMap (c => b map (d => c :+ d))
}
Results:
sequence(l1)
res8: scala.util.Try[Seq[Int]] = Failure(java.lang.Exception: failed)
sequence(l2)
res9: scala.util.Try[Seq[Int]] = Success(List(1, 2, 3, 5, 6))
It looks nice, though is there not going to be quite a performance hit with the append operation?
– J Pullar
Mar 19 '13 at 11:38
1
Fair point - I'd forgotten that the defaultSeq
is aList
. Add reverse/use a vector at your discretion!
– Impredicative
Mar 19 '13 at 14:07
Nice, I hadnt seen that foldLeft shortcut before/:
– Stephen
May 22 '17 at 6:06
add a comment |
A little less verbose, and more type safe:
def sequence[T](xs : Seq[Try[T]]) : Try[Seq[T]] = (Try(Seq[T]()) /: xs) {
(a, b) => a flatMap (c => b map (d => c :+ d))
}
Results:
sequence(l1)
res8: scala.util.Try[Seq[Int]] = Failure(java.lang.Exception: failed)
sequence(l2)
res9: scala.util.Try[Seq[Int]] = Success(List(1, 2, 3, 5, 6))
A little less verbose, and more type safe:
def sequence[T](xs : Seq[Try[T]]) : Try[Seq[T]] = (Try(Seq[T]()) /: xs) {
(a, b) => a flatMap (c => b map (d => c :+ d))
}
Results:
sequence(l1)
res8: scala.util.Try[Seq[Int]] = Failure(java.lang.Exception: failed)
sequence(l2)
res9: scala.util.Try[Seq[Int]] = Success(List(1, 2, 3, 5, 6))
edited Mar 19 '13 at 11:02
answered Mar 19 '13 at 10:55
ImpredicativeImpredicative
3,8641034
3,8641034
It looks nice, though is there not going to be quite a performance hit with the append operation?
– J Pullar
Mar 19 '13 at 11:38
1
Fair point - I'd forgotten that the defaultSeq
is aList
. Add reverse/use a vector at your discretion!
– Impredicative
Mar 19 '13 at 14:07
Nice, I hadnt seen that foldLeft shortcut before/:
– Stephen
May 22 '17 at 6:06
add a comment |
It looks nice, though is there not going to be quite a performance hit with the append operation?
– J Pullar
Mar 19 '13 at 11:38
1
Fair point - I'd forgotten that the defaultSeq
is aList
. Add reverse/use a vector at your discretion!
– Impredicative
Mar 19 '13 at 14:07
Nice, I hadnt seen that foldLeft shortcut before/:
– Stephen
May 22 '17 at 6:06
It looks nice, though is there not going to be quite a performance hit with the append operation?
– J Pullar
Mar 19 '13 at 11:38
It looks nice, though is there not going to be quite a performance hit with the append operation?
– J Pullar
Mar 19 '13 at 11:38
1
1
Fair point - I'd forgotten that the default
Seq
is a List
. Add reverse/use a vector at your discretion!– Impredicative
Mar 19 '13 at 14:07
Fair point - I'd forgotten that the default
Seq
is a List
. Add reverse/use a vector at your discretion!– Impredicative
Mar 19 '13 at 14:07
Nice, I hadnt seen that foldLeft shortcut before
/:
– Stephen
May 22 '17 at 6:06
Nice, I hadnt seen that foldLeft shortcut before
/:
– Stephen
May 22 '17 at 6:06
add a comment |
As an addition to Impredicative's answer and comment, if you have both scalaz-seven and scalaz-contrib/scala210 in your dependencies:
> scala210/console
[warn] Credentials file /home/folone/.ivy2/.credentials does not exist
[info] Starting scala interpreter...
[info]
Welcome to Scala version 2.10.0 (OpenJDK 64-Bit Server VM, Java 1.7.0_17).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import scala.util._
import scala.util._
scala> def map(l:List[Int]): List[Try[Int]] = l map {
| case 4 => Failure(new Exception("failed"))
| case i => Success(i)
| }
map: (l: List[Int])List[scala.util.Try[Int]]
scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._
scala> import scalaz.contrib.std.utilTry._
import scalaz.contrib.std.utilTry._
scala> val l1 = List(1,2,3,4,5,6)
l1: List[Int] = List(1, 2, 3, 4, 5, 6)
scala> map(l1).sequence
res2: scala.util.Try[List[Int]] = Failure(java.lang.Exception: failed)
scala> val l2 = List(1,2,3,5,6)
l2: List[Int] = List(1, 2, 3, 5, 6)
scala> map(l2).sequence
res3: scala.util.Try[List[Int]] = Success(List(1, 2, 3, 5, 6))
You need scalaz to get an Applicative
instance for the List
(hidden in the MonadPlus
instance), to get the sequence
method. You need scalaz-contrib for the Traverse
instance of Try
, which is required by the sequence
's type signature.
Try
lives outside of scalaz, since it only appeared in scala 2.10, and scalaz aims to cross-compile to earlier versions).
add a comment |
As an addition to Impredicative's answer and comment, if you have both scalaz-seven and scalaz-contrib/scala210 in your dependencies:
> scala210/console
[warn] Credentials file /home/folone/.ivy2/.credentials does not exist
[info] Starting scala interpreter...
[info]
Welcome to Scala version 2.10.0 (OpenJDK 64-Bit Server VM, Java 1.7.0_17).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import scala.util._
import scala.util._
scala> def map(l:List[Int]): List[Try[Int]] = l map {
| case 4 => Failure(new Exception("failed"))
| case i => Success(i)
| }
map: (l: List[Int])List[scala.util.Try[Int]]
scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._
scala> import scalaz.contrib.std.utilTry._
import scalaz.contrib.std.utilTry._
scala> val l1 = List(1,2,3,4,5,6)
l1: List[Int] = List(1, 2, 3, 4, 5, 6)
scala> map(l1).sequence
res2: scala.util.Try[List[Int]] = Failure(java.lang.Exception: failed)
scala> val l2 = List(1,2,3,5,6)
l2: List[Int] = List(1, 2, 3, 5, 6)
scala> map(l2).sequence
res3: scala.util.Try[List[Int]] = Success(List(1, 2, 3, 5, 6))
You need scalaz to get an Applicative
instance for the List
(hidden in the MonadPlus
instance), to get the sequence
method. You need scalaz-contrib for the Traverse
instance of Try
, which is required by the sequence
's type signature.
Try
lives outside of scalaz, since it only appeared in scala 2.10, and scalaz aims to cross-compile to earlier versions).
add a comment |
As an addition to Impredicative's answer and comment, if you have both scalaz-seven and scalaz-contrib/scala210 in your dependencies:
> scala210/console
[warn] Credentials file /home/folone/.ivy2/.credentials does not exist
[info] Starting scala interpreter...
[info]
Welcome to Scala version 2.10.0 (OpenJDK 64-Bit Server VM, Java 1.7.0_17).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import scala.util._
import scala.util._
scala> def map(l:List[Int]): List[Try[Int]] = l map {
| case 4 => Failure(new Exception("failed"))
| case i => Success(i)
| }
map: (l: List[Int])List[scala.util.Try[Int]]
scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._
scala> import scalaz.contrib.std.utilTry._
import scalaz.contrib.std.utilTry._
scala> val l1 = List(1,2,3,4,5,6)
l1: List[Int] = List(1, 2, 3, 4, 5, 6)
scala> map(l1).sequence
res2: scala.util.Try[List[Int]] = Failure(java.lang.Exception: failed)
scala> val l2 = List(1,2,3,5,6)
l2: List[Int] = List(1, 2, 3, 5, 6)
scala> map(l2).sequence
res3: scala.util.Try[List[Int]] = Success(List(1, 2, 3, 5, 6))
You need scalaz to get an Applicative
instance for the List
(hidden in the MonadPlus
instance), to get the sequence
method. You need scalaz-contrib for the Traverse
instance of Try
, which is required by the sequence
's type signature.
Try
lives outside of scalaz, since it only appeared in scala 2.10, and scalaz aims to cross-compile to earlier versions).
As an addition to Impredicative's answer and comment, if you have both scalaz-seven and scalaz-contrib/scala210 in your dependencies:
> scala210/console
[warn] Credentials file /home/folone/.ivy2/.credentials does not exist
[info] Starting scala interpreter...
[info]
Welcome to Scala version 2.10.0 (OpenJDK 64-Bit Server VM, Java 1.7.0_17).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import scala.util._
import scala.util._
scala> def map(l:List[Int]): List[Try[Int]] = l map {
| case 4 => Failure(new Exception("failed"))
| case i => Success(i)
| }
map: (l: List[Int])List[scala.util.Try[Int]]
scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._
scala> import scalaz.contrib.std.utilTry._
import scalaz.contrib.std.utilTry._
scala> val l1 = List(1,2,3,4,5,6)
l1: List[Int] = List(1, 2, 3, 4, 5, 6)
scala> map(l1).sequence
res2: scala.util.Try[List[Int]] = Failure(java.lang.Exception: failed)
scala> val l2 = List(1,2,3,5,6)
l2: List[Int] = List(1, 2, 3, 5, 6)
scala> map(l2).sequence
res3: scala.util.Try[List[Int]] = Success(List(1, 2, 3, 5, 6))
You need scalaz to get an Applicative
instance for the List
(hidden in the MonadPlus
instance), to get the sequence
method. You need scalaz-contrib for the Traverse
instance of Try
, which is required by the sequence
's type signature.
Try
lives outside of scalaz, since it only appeared in scala 2.10, and scalaz aims to cross-compile to earlier versions).
answered Mar 19 '13 at 12:59
folonefolone
5,7211155105
5,7211155105
add a comment |
add a comment |
Have a look on the liftweb Box monad. With the help of the tryo
constructor function, it gives you exactly the abstraction you are looking for.
With tryo
you can lift a function into a Box
. The box then either contains the result from the function or it contains an error. You can then access the box with the usual monadic helper functions (flatMap, filter, etc.), without bothering if the box contains an error or the result form the function.
Example:
import net.liftweb.util.Helpers.tryo
List("1", "2", "not_a_number") map (x => tryo(x.toInt)) map (_ map (_ + 1 ))
Results to
List[net.liftweb.common.Box[Int]] =
List(
Full(2),
Full(3),
Failure(For input string: "not_a_number",Full(java.lang.NumberFormatException: For input string: "not_a_number"),Empty)
)
You can skip the erroneous values with flatMap
List("1", "2", "not_a_number") map (x => tryo(x.toInt)) flatMap (_ map (_ + 1 ))
Results
List[Int] = List(2, 3)
There are multiple other helper methods, e.g. for combining boxes (while chaining error messages). You can find a good overview here: Box Cheat Sheet for Lift
You can use it on its own, no need to use the whole lift framework. For the examples above I used the follwing sbt script:
scalaVersion := "2.9.1"
libraryDependencies += "net.liftweb" %% "lift-common" % "2.5-RC2"
libraryDependencies += "net.liftweb" %% "lift-util" % "2.5-RC2"
add a comment |
Have a look on the liftweb Box monad. With the help of the tryo
constructor function, it gives you exactly the abstraction you are looking for.
With tryo
you can lift a function into a Box
. The box then either contains the result from the function or it contains an error. You can then access the box with the usual monadic helper functions (flatMap, filter, etc.), without bothering if the box contains an error or the result form the function.
Example:
import net.liftweb.util.Helpers.tryo
List("1", "2", "not_a_number") map (x => tryo(x.toInt)) map (_ map (_ + 1 ))
Results to
List[net.liftweb.common.Box[Int]] =
List(
Full(2),
Full(3),
Failure(For input string: "not_a_number",Full(java.lang.NumberFormatException: For input string: "not_a_number"),Empty)
)
You can skip the erroneous values with flatMap
List("1", "2", "not_a_number") map (x => tryo(x.toInt)) flatMap (_ map (_ + 1 ))
Results
List[Int] = List(2, 3)
There are multiple other helper methods, e.g. for combining boxes (while chaining error messages). You can find a good overview here: Box Cheat Sheet for Lift
You can use it on its own, no need to use the whole lift framework. For the examples above I used the follwing sbt script:
scalaVersion := "2.9.1"
libraryDependencies += "net.liftweb" %% "lift-common" % "2.5-RC2"
libraryDependencies += "net.liftweb" %% "lift-util" % "2.5-RC2"
add a comment |
Have a look on the liftweb Box monad. With the help of the tryo
constructor function, it gives you exactly the abstraction you are looking for.
With tryo
you can lift a function into a Box
. The box then either contains the result from the function or it contains an error. You can then access the box with the usual monadic helper functions (flatMap, filter, etc.), without bothering if the box contains an error or the result form the function.
Example:
import net.liftweb.util.Helpers.tryo
List("1", "2", "not_a_number") map (x => tryo(x.toInt)) map (_ map (_ + 1 ))
Results to
List[net.liftweb.common.Box[Int]] =
List(
Full(2),
Full(3),
Failure(For input string: "not_a_number",Full(java.lang.NumberFormatException: For input string: "not_a_number"),Empty)
)
You can skip the erroneous values with flatMap
List("1", "2", "not_a_number") map (x => tryo(x.toInt)) flatMap (_ map (_ + 1 ))
Results
List[Int] = List(2, 3)
There are multiple other helper methods, e.g. for combining boxes (while chaining error messages). You can find a good overview here: Box Cheat Sheet for Lift
You can use it on its own, no need to use the whole lift framework. For the examples above I used the follwing sbt script:
scalaVersion := "2.9.1"
libraryDependencies += "net.liftweb" %% "lift-common" % "2.5-RC2"
libraryDependencies += "net.liftweb" %% "lift-util" % "2.5-RC2"
Have a look on the liftweb Box monad. With the help of the tryo
constructor function, it gives you exactly the abstraction you are looking for.
With tryo
you can lift a function into a Box
. The box then either contains the result from the function or it contains an error. You can then access the box with the usual monadic helper functions (flatMap, filter, etc.), without bothering if the box contains an error or the result form the function.
Example:
import net.liftweb.util.Helpers.tryo
List("1", "2", "not_a_number") map (x => tryo(x.toInt)) map (_ map (_ + 1 ))
Results to
List[net.liftweb.common.Box[Int]] =
List(
Full(2),
Full(3),
Failure(For input string: "not_a_number",Full(java.lang.NumberFormatException: For input string: "not_a_number"),Empty)
)
You can skip the erroneous values with flatMap
List("1", "2", "not_a_number") map (x => tryo(x.toInt)) flatMap (_ map (_ + 1 ))
Results
List[Int] = List(2, 3)
There are multiple other helper methods, e.g. for combining boxes (while chaining error messages). You can find a good overview here: Box Cheat Sheet for Lift
You can use it on its own, no need to use the whole lift framework. For the examples above I used the follwing sbt script:
scalaVersion := "2.9.1"
libraryDependencies += "net.liftweb" %% "lift-common" % "2.5-RC2"
libraryDependencies += "net.liftweb" %% "lift-util" % "2.5-RC2"
answered Mar 19 '13 at 12:23
stefan.schwetschkestefan.schwetschke
7,93711827
7,93711827
add a comment |
add a comment |
These are my 2cents:
def sequence[A, M[_] <: TraversableOnce[_]](in: M[Try[A]])
(implicit cbf:CanBuildFrom[M[Try[A]], A, M[A]]): Try[M[A]] = {
in.foldLeft(Try(cbf(in))) {
(txs, tx) =>
for {
xs <- txs
x <- tx.asInstanceOf[Try[A]]
} yield {
xs += x
}
}.map(_.result())
}
add a comment |
These are my 2cents:
def sequence[A, M[_] <: TraversableOnce[_]](in: M[Try[A]])
(implicit cbf:CanBuildFrom[M[Try[A]], A, M[A]]): Try[M[A]] = {
in.foldLeft(Try(cbf(in))) {
(txs, tx) =>
for {
xs <- txs
x <- tx.asInstanceOf[Try[A]]
} yield {
xs += x
}
}.map(_.result())
}
add a comment |
These are my 2cents:
def sequence[A, M[_] <: TraversableOnce[_]](in: M[Try[A]])
(implicit cbf:CanBuildFrom[M[Try[A]], A, M[A]]): Try[M[A]] = {
in.foldLeft(Try(cbf(in))) {
(txs, tx) =>
for {
xs <- txs
x <- tx.asInstanceOf[Try[A]]
} yield {
xs += x
}
}.map(_.result())
}
These are my 2cents:
def sequence[A, M[_] <: TraversableOnce[_]](in: M[Try[A]])
(implicit cbf:CanBuildFrom[M[Try[A]], A, M[A]]): Try[M[A]] = {
in.foldLeft(Try(cbf(in))) {
(txs, tx) =>
for {
xs <- txs
x <- tx.asInstanceOf[Try[A]]
} yield {
xs += x
}
}.map(_.result())
}
answered Feb 8 '14 at 12:22
Filippo De LucaFilippo De Luca
444319
444319
add a comment |
add a comment |
Starting Scala 2.13
, most collections are provided with a partitionWith
method which partitions elements based on a function which returns either Right
or Left
.
In our case we can call partitionWith
with a function that transforms our Try
s into Either
s (Try::toEither
) in order to partition Success
es as Right
s and Failure
s as Left
s.
Then it's a simple matter of matching the resulting partitioned tuple of lefts and rights based on whether or not there are lefts:
tries.partitionWith(_.toEither) match {
case (Nil, rights) => Success(rights)
case (firstLeft :: _, _) => Failure(firstLeft)
}
// * val tries = List(Success(10), Success(20), Success(30))
// => Try[List[Int]] = Success(List(10, 20, 30))
// * val tries = List(Success(10), Success(20), Failure(new Exception("error1")))
// => Try[List[Int]] = Failure(java.lang.Exception: error1)
Details of the intermediate partitionWith
step:
List(Success(10), Success(20), Failure(new Exception("error1"))).partitionWith(_.toEither)
// => (List[Throwable], List[Int]) = (List(java.lang.Exception: error1), List(10, 20))
add a comment |
Starting Scala 2.13
, most collections are provided with a partitionWith
method which partitions elements based on a function which returns either Right
or Left
.
In our case we can call partitionWith
with a function that transforms our Try
s into Either
s (Try::toEither
) in order to partition Success
es as Right
s and Failure
s as Left
s.
Then it's a simple matter of matching the resulting partitioned tuple of lefts and rights based on whether or not there are lefts:
tries.partitionWith(_.toEither) match {
case (Nil, rights) => Success(rights)
case (firstLeft :: _, _) => Failure(firstLeft)
}
// * val tries = List(Success(10), Success(20), Success(30))
// => Try[List[Int]] = Success(List(10, 20, 30))
// * val tries = List(Success(10), Success(20), Failure(new Exception("error1")))
// => Try[List[Int]] = Failure(java.lang.Exception: error1)
Details of the intermediate partitionWith
step:
List(Success(10), Success(20), Failure(new Exception("error1"))).partitionWith(_.toEither)
// => (List[Throwable], List[Int]) = (List(java.lang.Exception: error1), List(10, 20))
add a comment |
Starting Scala 2.13
, most collections are provided with a partitionWith
method which partitions elements based on a function which returns either Right
or Left
.
In our case we can call partitionWith
with a function that transforms our Try
s into Either
s (Try::toEither
) in order to partition Success
es as Right
s and Failure
s as Left
s.
Then it's a simple matter of matching the resulting partitioned tuple of lefts and rights based on whether or not there are lefts:
tries.partitionWith(_.toEither) match {
case (Nil, rights) => Success(rights)
case (firstLeft :: _, _) => Failure(firstLeft)
}
// * val tries = List(Success(10), Success(20), Success(30))
// => Try[List[Int]] = Success(List(10, 20, 30))
// * val tries = List(Success(10), Success(20), Failure(new Exception("error1")))
// => Try[List[Int]] = Failure(java.lang.Exception: error1)
Details of the intermediate partitionWith
step:
List(Success(10), Success(20), Failure(new Exception("error1"))).partitionWith(_.toEither)
// => (List[Throwable], List[Int]) = (List(java.lang.Exception: error1), List(10, 20))
Starting Scala 2.13
, most collections are provided with a partitionWith
method which partitions elements based on a function which returns either Right
or Left
.
In our case we can call partitionWith
with a function that transforms our Try
s into Either
s (Try::toEither
) in order to partition Success
es as Right
s and Failure
s as Left
s.
Then it's a simple matter of matching the resulting partitioned tuple of lefts and rights based on whether or not there are lefts:
tries.partitionWith(_.toEither) match {
case (Nil, rights) => Success(rights)
case (firstLeft :: _, _) => Failure(firstLeft)
}
// * val tries = List(Success(10), Success(20), Success(30))
// => Try[List[Int]] = Success(List(10, 20, 30))
// * val tries = List(Success(10), Success(20), Failure(new Exception("error1")))
// => Try[List[Int]] = Failure(java.lang.Exception: error1)
Details of the intermediate partitionWith
step:
List(Success(10), Success(20), Failure(new Exception("error1"))).partitionWith(_.toEither)
// => (List[Throwable], List[Int]) = (List(java.lang.Exception: error1), List(10, 20))
answered Jan 19 at 23:53
Xavier GuihotXavier Guihot
6,87482234
6,87482234
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f15495678%2fflatten-scala-try%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
Please say how your result should look like.
List(1, 2, 3, Exception, 5, 7)
?– Malte Schwerhoff
Mar 19 '13 at 9:41
1
Scalaz would call this operation
sequence
, but it's sadly missing from the standard library.– Impredicative
Mar 19 '13 at 10:29