If I have a following method
def getMyList :\/[Throwable,List[\/[Throwable,Int]]] ={
....
}
how to flatten type of getMyList
to \/[Throwable,List[Int]]
If I have a following method
def getMyList :\/[Throwable,List[\/[Throwable,Int]]] ={
....
}
how to flatten type of getMyList
to \/[Throwable,List[Int]]
Just flatMap
and sequenceU
, it's all in scalaz:
def flatten(e: \/[Throwable,List[\/[Throwable,Int]]]): \/[Throwable,List[Int]] = {
e.flatMap(a => a.sequenceU)
}
sequenceU
automatically infers the right type constructor for the Applicative
instance. Here's an article worth reading on the subject: eed3si9n.com/learning-scalaz-day15 –
Spiritualism \/[Throwable,List[Int]]
earlier on. –
Spriggs getMyList
, it may be possible to replace a map across the List and sequenceU
with traverseU
. –
Spriggs If by flatten, you mean remove the left types from List[\/[Throwable,Int]]
, then you can map
the outer disjunction, and collect
the right types:
list.map(_.collect{ case \/-(x) => x})
I don't think that some higher order "flatten" exists for /. Looks like Validateion & ValidationNEL will be better choice for this problem. However here is "dirty" solution for /, it will return first fail. If you want to accumulate failures Validation is way to go
val getMyList: \/[Throwable,List[\/[Throwable,Int]]] =
//\/-(List(-\/(new RuntimeException("test")), \/-(1)))
\/-(List(\/-(2), \/-(1)))
val flatten = getMyList.fold(\/.left, _.foldLeft(\/.right[Throwable, List[Int]](List.empty[Int])) {
case (\/-(list), \/-(i)) => \/-(list :+ i)
case (\/-(list), -\/(err)) => -\/(err)
case (-\/(err), _) => -\/(err)
})
println(flatten)
join
in BindSyntax
- github.com/scalaz/scalaz/blob/series/7.1.x/core/src/main/scala/…. This provides join
which is essentially synonymous with flatten
for all types A
which have a Bind[A]
. –
Spriggs We use the following method, where .sSuccess creates a \/[_, Seq[T]]
and .sFail creates a \/[Throwable, _]
with all of the throwables' error messages concatenated:
implicit class CondenseEither[T](seq: Seq[\/[Throwable,T]]) = {
def condenseSeq: \/[Throwable, Seq[T]] = {
val errs = seq.filter(_.isLeft).map(_.toEither)
if(errs.isEmpty) seq.map(_.toEither).map(_.right.get).sSuccess
else errs.map(_.left.get.getMessage).mkString(", ")).sFail
}
}
There's probably a way to do this without the toEither
s
© 2022 - 2024 — McMap. All rights reserved.
sequenceU
. I tried with ordinarysequence
but failed. – Grizzly