Just for the sake of quick clarity for someone who wants to start working with Scala FP library, on a journey to become better at pure FP.
Would someone clarify the dif
Scalaz started as an attempt to port to Scala some well-established abstractions from Haskell (like typeclasses for Monad, Functor and much more). Problem with it was, that it doesn't have great documentation, so basically, you needed to use documentation of Haskell libraries in order to understand how to use certain Scalaz resources. Nowadays, you there's Sam Halliday’s Functional Programming for Mortals which you can use as a learning source for Scalaz.
Cats was created later, as essentially reimplementation what Scalaz provided. Cats has a lot better documentation than Scalaz, there is also great book Scala with Cats.
Scalaz and Cats might have very similar purposes, so they're competing as general purpose FP library for Scala. There are also libraries that serve as compatibility-layer between both libraries.
Cats-Effect is a library, which provides "standard" IO monad for Scala (again idea borrowed from Haskell (?)). It depends on code from Cats core library.
You can read more here why there is a need for IO monad for Scala, when there's standard's library Future.
Monix is another library, which provides an IO monad for Scala, but this time it's called Task
. It was meant to be a more high-level abstraction and provide easier interop with code using standard library Future. In reality, it shares a lot of code with Cats-Effect and creator of Monix Alexandru Nedelcu is also one of the main contributors of Cats-Effect.
Here you may find more information about the differences between cats.effect.IO
and monix.eval.Task
, as well as some of the history of both.
Lastly, there is ZIO which started as an attempt to reimplement IO monad for Scalaz, but ended up as a completely separate library (so it does not depend on Scalaz codebase).
The great thing about all libraries is, they're all implementing typeclasses (like Sync or Concurrent) from Cats-Effect, so using pattern called tagless final you're able to switch between implementation.
That hierarchy of typeclasses also serve as an interpolation library between, many (all (?)) of the IO implementations (as by the time it was created there already were fs2.Task
, monix.Task
& scalaz.IO
). Also, apparently, in a future the IO part may be moved into another module, leaving only the interoperability typeclasses.
If you don't use tagless final you can still use modules that provide interop between certain IO monads, for example zio-interop-cats (between ZIO and Cats-Effect or catnap for Monix-Cats-Effect.