Last active
November 7, 2020 13:22
-
-
Save afsalthaj/9d9b3f79de5638c88c6cd53a2242a1b8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cats.data.StateT | |
import cats.effect.{ IO, Resource } | |
import cats.syntax.traverse._ | |
import cats.instances.list._ | |
import Resources.StateInfo | |
final case class Resources[A](resources: List[Resource[IO, A]]) { | |
def executeAll: Resource[IO, List[A]] = | |
resources.sequence[Resource[IO, *], A] | |
/** | |
* @param f: Given a list of B (derived from A) already processed, and the current file A, execute the process to derive C. | |
* Resources are closed as an when they are used, unlike `execute`. Example: `Resources.trackDuplicate` | |
*/ | |
def use[B, C](f: (List[B], A) => IO[C])(g: A => B): IO[List[C]] = | |
resources | |
.traverse[StateInfo[B, *], C](resource => { | |
for { | |
existingFiles <- StateT.get[IO, List[B]] | |
dataB <- StateT.liftF(resource.use(data => f(existingFiles, data).map(b => (data, b)))) | |
_ <- StateT.set[IO, List[B]](g(dataB._1) :: existingFiles) | |
} yield dataB._2 | |
}) | |
.run(Nil: List[B]) | |
.map(_._2) | |
} | |
object Resources { | |
type StateInfo[A, B] = StateT[IO, List[A], B] | |
def trackDuplicate[A, B, C]( | |
f: A => IO[C] | |
)(g: A => B)(onDuplicate: B => String): (List[B], A) => IO[C] = { (state, resource) => | |
if (state.contains(g(resource))) { | |
IO.raiseError(new RuntimeException(onDuplicate(g(resource)))) | |
} else f(resource) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment