Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flatten nested Ior's with scala-cats

Working with scala-cat's Ior data type I encountered the following problem:

import cats._
import cats.data._
import cats.implicits._

type Locale = String
type FailureMessage = String
type Failures = NonEmptyList[FailureMessage]

private def listTranslationFiles(): IO[FailureMessage Either Array[File]] = ???

private def analyzeTranslationFiles(fs: Array[File]): Failures Ior Seq[(Locale, File)] = ???

private def readTranslations(): IO[Failures Ior Seq[(Locale, File)]] = for {
    files <- listTranslationFiles()
    fileIor = if(files.isLeft) (NonEmptyList(files.left.get, Nil): Failures).leftIor
              else files.right.get.rightIor
    // fileIor: Ior[Failures, Array[File]]
    analyzed = fileIor.bimap(identity, analyzeTranslationFiles)
    // analyzed: Ior[Failures, Ior[Failures, Seq[(Locale, File)]]]
    result = ??? //  how do I 'flatten' analyzed here?
} yield result

In my last step I need to convert this type:

Ior[Failures, Ior[Failures, Seq[(Locale, File)]]]

into:

Ior[Failures, Seq[(Locale, File)]]

by somehow flattening the Ior (I want to accumulate all left Ior's into the top-level Ior). How can this be achieved?

like image 719
Florian Baierl Avatar asked Dec 29 '25 09:12

Florian Baierl


1 Answers

You can literally just replace the ??? in result = ??? with analyzed.flatten in your code and it will work perfectly, thanks to the flatten syntax method provided by FlatMap and the fact that Ior has a FlatMap instance when the left side is a semigroup (as it is here).

You can do a little better than that by replacing these two lines:

analyzed = fileIor.bimap(identity, analyzeTranslationFiles)
result = analyzed.flatten

With the following:

result = fileIor.flatMap(analyzeTranslationFiles)

…since any time you're using bimap with identity on the left side, you can replace it with map, and any time you're using map and then flatten, you can replace both with flatMap.

like image 121
Travis Brown Avatar answered Jan 01 '26 19:01

Travis Brown



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!