How to smooth a disjunction

If I have the following method

def getMyList :\/[Throwable,List[\/[Throwable,Int]]] ={ .... } 

how to smooth getMyList type to \/[Throwable,List[Int]]

+6
source share
4 answers

Just flatMap and sequenceU , all in scalaz:

  def flatten(e: \/[Throwable,List[\/[Throwable,Int]]]): \/[Throwable,List[Int]] = { e.flatMap(a => a.sequenceU) } 
+9
source

If using flatten you want to remove left types from List[\/[Throwable,Int]] , then you can map external clause, and collect correct types:

 list.map(_.collect{ case \/-(x) => x}) 
+1
source

I do not think that there is some higher "smoothing" order for /. It seems that Validateion and ValidationNEL will be the best choice for this problem. However, here is a "dirty" solution for /, it will return first with an error. If you want to copy errors, validation is the 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) 
0
source

We use the following method in which .sSuccess creates \/[_, Seq[T]] and .sFail creates \/[Throwable, _] with all concatenated compilation error messages:

 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 is probably a way to do this without toEither s

0
source

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


All Articles