Scalaz: Type Classes and Functional Data Structures for Scala
Principled Functional Programming in Scala
At a glance
- What is it?
- Scalaz is a Scala library that adds a refined type class hierarchy and purely functional data structures to the standard library. It targets Scala developers who want category-theory-based abstractions without pulling in the Typelevel ecosystem.
- Who is it for?
- Scalaz suits Scala developers who want a self-contained functional programming library with a precise type class hierarchy and no dependency on the Typelevel stack. It is not the right choice for teams already using http4s, Doobie, or fs2, since those libraries interoperate through Cats Effect types.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Scala, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Scalaz provides that the Scala standard library does not
The Scala standard library ships Option, List, Future, and Either, but it does not define a general abstraction for structures that can be mapped over, chained, or combined. Scalaz fills that gap with a hierarchy of type classes: Functor, Apply, Applicative, Bind, Monad, Foldable, Traverse, MonadPlus, and others. Each type class captures a precise law that any conforming instance must satisfy. A function constrained to Functor[M] works with any data structure that has a valid map operation, whether that is Option, List, or a custom IO type. The caller does not need to know the concrete type.
Beyond type classes, Scalaz ships data structures absent from the standard library. NonEmptyList is a list type that the compiler guarantees to be non-empty, making certain runtime errors impossible. Validation accumulates errors rather than short-circuiting like Either, which matters for form validation and configuration parsing. The library also provides monad transformers such as EitherT, OptionT, WriterT, and StateT, allowing composition of effects without wrapping effects manually.
Type class instance placement and the scalaz.std design
A notable design decision in Scalaz 7 separates type class definitions from their instances. In Scalaz 6, instances were scattered across companion objects and could cause ambiguous implicit errors when a type like (A, B) had multiple valid derivations. Scalaz 7 moves standard library instances into the package `scalaz.std`. Instances for Option live in `scalaz.std.option`, instances for List live in `scalaz.std.list`, and so on. Each is a trait that can be mixed into an object for mass import.
The inheritance hierarchy is strict: Monad extends Applicative, which extends Apply, which extends Functor. This means a function requiring a Functor[M] constraint accepts any Monad[M] argument without an explicit upcast. The following snippet from the README demonstrates this:
def bar[M[_]: Functor] = ()
def foo[M[_]: Monad] = bar[M] // Monad[M] is a subtype of Functor[M]Scalaz also provides syntax through `scalaz.syntax`. Importing `syntax.bind._` adds extension methods like `join` and `ifM` directly to List or Option values, so the library can be used either with explicit type class calls or with operator syntax, depending on team preference.
Adding Scalaz to an SBT project and first use
The current stable release is 7.3.9. For an SBT project, the README gives this dependency declaration:
libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.3.9"This adds `scalaz-core`, which is the main module: type class hierarchy, standard library instances, and syntax. Two additional sub-projects exist as separate artifacts: `scalaz-effect` for IO effect representations in the type system, and `scalaz-iteratee` as an experimental streaming abstraction. For Maven and other build tools, the README points to `search.maven.org` with group `org.scalaz` and version `7.3.9` to find all available modules with sample configuration snippets.
Once the dependency is on the classpath, a quick check from the README shows how to call Apply directly:
import scalaz._
import std.option._, std.list._
Apply[Option].apply2(some(1), some(2))((a, b) => a + b)
// res0: Option[Int] = Some(3)
Traverse[List].traverse(List(1, 2, 3))(i => some(i))
// res1: Option[List[Int]] = Some(List(1, 2, 3))The first line imports everything; the second brings Option and List instances into scope. `Apply[Option]` calls look up the Apply instance from the imported instances. For developers who prefer everything at once, the README notes that `import Scalaz._` imports type class instances, syntax, and operator aliases together.
Scalaz Validation versus Either: when to use each
The standard library's Either stops at the first Left in a for-comprehension. Scalaz's Validation collects all failures and returns them together. The typical form is ValidationNel, meaning Validation[NonEmptyList[E], A], where E is the error type. A function parsing multiple form fields can return a ValidationNel for each field, and then accumulate all failures into a single NonEmptyList at the end. This matters when the caller wants to see every error, not just the first one.
Because Validation is not a Monad, it cannot appear in a for-comprehension without losing the accumulation behaviour. The library documents this constraint intentionally. Developers reaching for Validation after working with Either sometimes find this surprising, but the restriction is what makes accumulation safe. Scalaz provides the Applicative interface for combining Validations with Apply, which keeps error accumulation intact.
For short-circuiting error handling where the first failure ends the computation, Either remains the standard choice. Scalaz's `\/:` (disjunction type) is a functional equivalent with additional type class instances, but for code that must interoperate with standard library Either, the built-in type is simpler.
Scalaz vs Cats: architectural differences
Cats is the other major functional programming library for Scala, and both it and Scalaz share a vocabulary of Functor, Monad, Traverse, and related type classes. The practical differences are architectural. Cats separates a kernel module containing foundational type classes from its main library, which keeps the dependency footprint smaller when a downstream library only needs basic abstractions. Cats ships a companion ecosystem called Cats Effect for managing IO and resource lifecycles, and libraries such as http4s, Doobie, and fs2 are built on top of that ecosystem.
Scalaz's effect module is `scalaz-effect`, which represents IO in the type system but does not provide the full IORuntime and fiber model that Cats Effect does. For teams already depending on http4s or Doobie, Cats is the natural fit because those libraries use Cats Effect type class instances throughout. Scalaz is a better choice for a codebase that wants the type class hierarchy without the Typelevel framework, or for existing codebases that adopted Scalaz before Cats reached maturity.
The README directs questions to an IRC channel on libera.chat (#scalaz) and a mailing list on Google Groups, while Cats concentrates its community on Discord. Both projects are active, but Scalaz has a longer history and a stable API that changes less frequently.
Scala.js, Scala Native, and cross-compilation support
The README states that Scalaz 7.3.9 is cross-built against Scala 2.12.x, 2.13.x, 3.x, Scala.js, and Scala Native. Cross-compilation to Scala.js makes Scalaz type classes available in browser-executed code, which matters for full-stack Scala applications where the same domain logic runs on the server and in the browser. Scala Native support extends the reach to ahead-of-time compiled binaries without a JVM.
The build file is `build.sbt` and the repository includes an `sbt` wrapper script. Contributors need a JDK and SBT to build the project. The `.java-version` file in the root suggests a specific Java version for the build environment, and `.jvmopts` sets JVM options for the build process. The `scalafix.conf` file indicates that the repository uses the Scalafix migration tool for automated code rewrites, which is useful when upgrading Scala versions.
The modular layout separates `core/`, `effect/`, `iteratee/`, `scalacheck-binding/`, and `tests/` into distinct source trees. The `example/` directory contains runnable Scalaz snippets referenced in the README as a starting point for exploring the library.
License, maintenance, and upgrade cost
The repository lists its license as NOASSERTION in the metadata, meaning the automated SPDX detection did not identify the license file. The full text is in `LICENSE.txt` at the root of the repository. Before including Scalaz in a commercial or redistributed product, read `LICENSE.txt` directly to confirm the terms.
The last push to the repository was on 2026-09-19, which places it within normal development cadence. The repository has no GitHub releases listed, but the README documents 7.3.9 as the current stable release. The wiki contains release and migration notes for version upgrades. Upgrading from Scalaz 6 to 7 required significant changes due to the reorganization of type class instances, and the wiki documents those changes. Upgrading within Scalaz 7.x is lower risk because the API is more stable, but the README cautions that some method signatures were adjusted for standalone usage, so compilation errors are the expected signal to check for breaking changes.
Editorial conclusion
Scalaz suits Scala developers who want a self-contained functional programming library with a precise type class hierarchy and no dependency on the Typelevel stack. It is not the right choice for teams already using http4s, Doobie, or fs2, since those libraries interoperate through Cats Effect types. Before adopting Scalaz, verify the license terms in LICENSE.txt cover your intended use, confirm that version 7.3.9 is cross-built for your Scala version, and check the migration wiki if you are upgrading from Scalaz 6.
Frequently asked questions
What modules make up Scalaz 7.3.9?
Scalaz 7.3.9 ships three modules: scalaz-core contains the type class hierarchy, data structures, and standard library instances; scalaz-effect adds IO effect types; scalaz-iteratee provides an experimental iteratee-based streaming abstraction. Most projects only need scalaz-core.
Does Scalaz support Scala 3?
The README states that Scalaz 7.3.9 is cross-built against Scala 2.12.x, 2.13.x, and 3.x, as well as Scala.js and Scala Native.
What is the difference between Scalaz Validation and Either?
Either short-circuits on the first failure. Scalaz Validation accumulates all failures into a NonEmptyList and returns them together, which is the right choice for input validation where callers need to see every error. Because Validation is not a Monad, it cannot be used in a for-comprehension without losing that accumulation.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/scalaz-scalaz)