Scalaz最初是为了尝试将一些来自 Haskell 的成熟抽象(如 Monad、Functor 等的类型类)移植到 Scala。问题在于,它没有很好的文档,所以基本上,您需要使用 Haskell 库的文档来了解如何使用某些Scalaz资源。现在,您可以使用 Sam Halliday 的《凡人函数式编程》作为Scalaz的学习资源。
Cats是后来创建的,本质上是重新实现Scalaz提供的功能。Cats有比Scalaz更好的文档,还有一本很棒的书 Scala with Cats。
Scalaz和Cats的用途可能非常相似,因此它们作为 Scala 的通用 FP 库进行竞争。还有一些库充当两个库之间的兼容性层。
Cats-Effect是一个库,它为 Scala 提供“标准” IO monad(同样的想法是从 Haskell (?) 借来的)。它依赖于Cats核心库中的代码。
当有标准库Future时,您可以在此处阅读更多信息,为什么 Scala 需要IO monad 。
Monix是另一个库,它为 Scala 提供了一个IO monad,但这次它被称为Task
. 它旨在成为更高级别的抽象,并使用标准库Future提供更容易的代码互操作。实际上,它与Cats-Effect共享大量代码, Monix Alexandru Nedelcu的创建者也是Cats-Effect的主要贡献者之一。
在这里cats.effect.IO
,您可以找到有关和之间差异的更多信息monix.eval.Task
,以及两者的一些历史。
最后,ZIO最初是为了尝试为Scalaz重新实现IO monad,但最终成为一个完全独立的库(因此它不依赖于Scalaz代码库)。
所有库的伟大之处在于,它们都从Cats-Effect实现类型类(如Sync或Concurrent ) ,因此使用称为无标记 final的模式,您可以在实现之间切换。
该类型类的层次结构还用作许多(全部(?))IO实现之间的插值库(就像在创建它时已经存在fs2.Task
, monix.Task
& scalaz.IO
)。此外,显然,将来IO部分可能会移到另一个模块中,只留下互操作性类型类。
如果您不使用无标记 final,您仍然可以使用在某些IO monad 之间提供互操作的模块,例如zio-interop-cats(在ZIO和Cats-Effect之间或Monix - Cats-Effect的catnap之间。
供您参考,我最近将此答案扩展为完整的博客文章。