Skip to content

Instantly share code, notes, and snippets.

@fanf
Last active September 14, 2019 16:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fanf/f541ad811bf1b010324fce7ae21f3224 to your computer and use it in GitHub Desktop.
Save fanf/f541ad811bf1b010324fce7ae21f3224 to your computer and use it in GitHub Desktop.
Select a callback given a value, and exec an associated callback
class Callbacks[A, E, CE] {
// callbacks are all returning Units with a generic callback error `CE` type.
type READER = IO[E, (Int, IO[CE, Unit])]
def reader1(): READER = ???
def reader2(): READER = ???
def reader3(): READER = ???
// manager function call readers, does its business decision algo and return according callback
def manager(readers: List[READER]): READER = {
// default callback (if no readers // no reader with positive value) does nothing
val defaultReader: IO[E, (Int, IO[CE, Unit])] = (0, UIO.unit).succeed
// loop over reader to find the one with the highest score - here, it's just value, nothing is executed
readers.foldLeft(defaultReader) { case (current, next) =>
current.zipWith(next) { case ((cr, cc), (nr, nc)) =>
if(cr > nr) (cr, cc) else (nr, nc)
}
}
}
// now, actually do the whole programm logic, first get the callback, then exec it - it's
// still a value, nothing is run
val readWriteProg = for {
chosen <- manager(List(reader1(), reader2(), reader3()))
_ <- IO.effect(println(s"Max value found: ${chosen._1}"))
written <- chosen._2 // exec selected callback
} yield ()
// run program, end of the world - assuming you have a ZIO runtime at hand:
new DefaultRuntime(){}.unsafeRunSync(readWriteProg)
}
@frankdavid
Copy link

Thanks for the idea! This looks like what I imagined could be a good solution, thank you for working it out.

@fanf
Copy link
Author

fanf commented Sep 14, 2019

@frankdavid: no pb, my pleasure

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment