Scalaz-core provides essential functional programming abstractions for Scala including type classes, data structures, and monad transformers.
—
Scalaz provides implicit conversions and operators that extend standard types with functional programming methods, creating a convenient DSL for type class operations.
Extensions for types with Functor instances.
// Available via import scalaz.syntax.functor._ or import scalaz.Scalaz._
implicit class FunctorOps[F[_], A](self: F[A])(implicit F: Functor[F]) {
/** Map over the contained value */
def map[B](f: A => B): F[B] = F.map(self)(f)
/** Alias for map */
def <$>[B](f: A => B): F[B] = F.map(self)(f)
/** Discard the value, keeping structure */
def void: F[Unit] = F.void(self)
/** Pair original with result of function */
def fproduct[B](f: A => B): F[(A, B)] = F.fproduct(self)(f)
/** Replace all values with constant */
def as[B](b: => B): F[B] = F.map(self)(_ => b)
/** Strengthen with value on left */
def strengthL[B](b: B): F[(B, A)] = F.map(self)(a => (b, a))
/** Strengthen with value on right */
def strengthR[B](b: B): F[(A, B)] = F.map(self)(a => (a, b))
}Usage Examples:
import scalaz._
import scalaz.syntax.functor._
List(1, 2, 3) <$> (_ * 2) // List(2, 4, 6)
List(1, 2, 3).void // List((), (), ())
List(1, 2, 3).fproduct(_ * 2) // List((1,2), (2,4), (3,6))
List(1, 2, 3).as("x") // List("x", "x", "x")Extensions for types with Applicative instances.
// Available via import scalaz.syntax.applicative._ or import scalaz.Scalaz._
implicit class ApplicativeOps[F[_], A](self: F[A])(implicit F: Applicative[F]) {
/** Applicative builder for combining values */
def |@|[B](fb: F[B]): ApplicativeBuilder[F, A, B]
/** Apply a function in context */
def <*>[B](f: F[A => B]): F[B] = F.ap(self)(f)
/** Sequence and discard left value */
def *>[B](fb: F[B]): F[B] = F.apply2(self, fb)((_, b) => b)
/** Sequence and discard right value */
def <*[B](fb: F[B]): F[A] = F.apply2(self, fb)((a, _) => a)
}
implicit class ApplicativeBuilder[F[_], A, B](self: F[A] |@| F[B]) {
/** Apply binary function */
def apply[C](f: (A, B) => C): F[C]
/** Extend to ternary */
def |@|[C](fc: F[C]): ApplicativeBuilder3[F, A, B, C]
/** Create tuple */
def tupled: F[(A, B)]
}
// Point syntax for lifting values
implicit class ApplicativePointOps[A](self: A) {
def point[F[_]](implicit F: Applicative[F]): F[A] = F.point(self)
def pure[F[_]](implicit F: Applicative[F]): F[A] = F.point(self)
}Usage Examples:
import scalaz._
import scalaz.syntax.applicative._
import scalaz.std.option._
// Applicative builder
val result = (some(1) |@| some(2) |@| some(3))(_ + _ + _) // Some(6)
// Point syntax
42.point[Option] // Some(42)
"hello".point[List] // List("hello")
// Sequencing
some(1) *> some(2) // Some(2)
some(1) <* some(2) // Some(1)Extensions for types with Monad instances.
// Available via import scalaz.syntax.monad._ or import scalaz.Scalaz._
implicit class MonadOps[F[_], A](self: F[A])(implicit F: Monad[F]) {
/** Monadic bind (flatMap) */
def >>=[B](f: A => F[B]): F[B] = F.bind(self)(f)
/** Alias for bind */
def flatMap[B](f: A => F[B]): F[B] = F.bind(self)(f)
/** Sequence and discard left value */
def >>[B](fb: => F[B]): F[B] = F.bind(self)(_ => fb)
/** Kleisli composition */
def >=>[B](f: A => F[B]): A => F[B] = a => F.bind(self)(f)
/** Join nested monads */
def join[B](implicit ev: A <:< F[B]): F[B] = F.join(self.map(ev))
/** Conditional execution */
def whenM(cond: F[Boolean])(implicit F: Monad[F]): F[Unit]
def unlessM(cond: F[Boolean])(implicit F: Monad[F]): F[Unit]
}
// Guard and filtering
implicit class MonadGuardOps[F[_]](implicit F: MonadPlus[F]) {
def guard(condition: Boolean): F[Unit] = F.guard(condition)
def prevent(condition: Boolean): F[Unit] = F.guard(!condition)
}Usage Examples:
import scalaz._
import scalaz.syntax.monad._
import scalaz.std.list._
// Monadic bind
List(1, 2) >>= (x => List(x, x * 2)) // List(1, 2, 2, 4)
// Sequencing
List(1, 2) >> List(10, 20) // List(10, 20, 10, 20)
// For comprehensions work automatically
val result = for {
x <- List(1, 2)
y <- List(10, 20)
} yield x + yExtensions for types with Foldable instances.
// Available via import scalaz.syntax.foldable._ or import scalaz.Scalaz._
implicit class FoldableOps[F[_], A](self: F[A])(implicit F: Foldable[F]) {
/** Fold with monoid */
def fold(implicit A: Monoid[A]): A = F.fold(self)
/** Map and fold */
def foldMap[B](f: A => B)(implicit B: Monoid[B]): B = F.foldMap(self)(f)
/** Right fold */
def foldRight[B](z: => B)(f: (A, => B) => B): B = F.foldRight(self, z)(f)
/** Left fold */
def foldLeft[B](z: B)(f: (B, A) => B): B = F.foldLeft(self, z)(f)
/** Convert to List */
def toList: List[A] = F.toList(self)
/** Length */
def length: Int = F.length(self)
/** Check if all satisfy predicate */
def all(p: A => Boolean): Boolean = F.all(self)(p)
/** Check if any satisfy predicate */
def any(p: A => Boolean): Boolean = F.any(self)(p)
/** Check if empty */
def empty: Boolean = F.empty(self)
/** Find element */
def find(p: A => Boolean): Option[A] = F.find(self)(p)
/** Count elements satisfying predicate */
def count(p: A => Boolean): Int = F.count(self)(p)
/** Sum elements */
def sum(implicit A: Monoid[A]): A = F.fold(self)
/** Product elements */
def product(implicit A: Monoid[A]): A = F.fold(self)
/** Maximum element */
def maximum(implicit A: Order[A]): Option[A] = F.maximum(self)
/** Minimum element */
def minimum(implicit A: Order[A]): Option[A] = F.minimum(self)
}Usage Examples:
import scalaz._
import scalaz.syntax.foldable._
import scalaz.std.list._
List(1, 2, 3, 4).foldMap(_.toString) // "1234"
List(1, 2, 3, 4).all(_ > 0) // true
List(1, 2, 3, 4).any(_ > 3) // true
List(1, 2, 3, 4).count(_ % 2 == 0) // 2
List("a", "b", "c").find(_ == "b") // Some("b")Extensions for types with Traverse instances.
// Available via import scalaz.syntax.traverse._ or import scalaz.Scalaz._
implicit class TraverseOps[F[_], A](self: F[A])(implicit F: Traverse[F]) {
/** Traverse with effects */
def traverse[G[_], B](f: A => G[B])(implicit G: Applicative[G]): G[F[B]] = F.traverse(self)(f)
/** Sequence effects */
def sequence[G[_], B](implicit ev: A <:< G[B], G: Applicative[G]): G[F[B]] = F.sequence(self.map(ev))
/** Map with accumulating state */
def mapAccumL[S, B](z: S)(f: (S, A) => (S, B)): (S, F[B]) = F.mapAccumL(self, z)(f)
/** Map with accumulating state (right) */
def mapAccumR[S, B](z: S)(f: (S, A) => (S, B)): (S, F[B]) = F.mapAccumR(self, z)(f)
/** Reverse the structure */
def reverse: F[A] = F.reverse(self)
}Usage Examples:
import scalaz._
import scalaz.syntax.traverse._
import scalaz.std.list._
import scalaz.std.option._
// Traverse with Option
List(1, 2, 3).traverse(x => if (x > 0) Some(x * 2) else None) // Some(List(2, 4, 6))
// Sequence List of Options
List(Some(1), Some(2), Some(3)).sequence // Some(List(1, 2, 3))
List(Some(1), None, Some(3)).sequence // NoneExtensions for types with Equal instances.
// Available via import scalaz.syntax.equal._ or import scalaz.Scalaz._
implicit class EqualOps[A](self: A)(implicit A: Equal[A]) {
/** Type-safe equality */
def ===(other: A): Boolean = A.equal(self, other)
/** Type-safe inequality */
def /==(other: A): Boolean = !A.equal(self, other)
/** Assert equality (throws if false) */
def assert_===(other: A): A = {
if (!A.equal(self, other)) sys.error(s"Assertion failed: $self === $other")
self
}
}Usage Examples:
import scalaz._
import scalaz.syntax.equal._
import scalaz.std.anyVal._
1 === 1 // true (uses Equal[Int])
1 /== 2 // true
"a" === "a" // true (uses Equal[String])
// Prevents comparison of different types
// 1 === "1" // Compilation error!Extensions for types with Order instances.
// Available via import scalaz.syntax.order._ or import scalaz.Scalaz._
implicit class OrderOps[A](self: A)(implicit A: Order[A]) {
/** Compare and return Ordering */
def ?|?(other: A): Ordering = A.order(self, other)
/** Less than */
def <(other: A): Boolean = A.lessThan(self, other)
/** Less than or equal */
def <=(other: A): Boolean = A.lessThanOrEqual(self, other)
/** Greater than */
def >(other: A): Boolean = A.greaterThan(self, other)
/** Greater than or equal */
def >=(other: A): Boolean = A.greaterThanOrEqual(self, other)
/** Maximum */
def max(other: A): A = A.max(self, other)
/** Minimum */
def min(other: A): A = A.min(self, other)
/** Sort with another value */
def sort(other: A): (A, A) = if (A.lessThanOrEqual(self, other)) (self, other) else (other, self)
}Usage Examples:
import scalaz._
import scalaz.syntax.order._
import scalaz.std.anyVal._
5 ?|? 3 // Ordering.GT
5 > 3 // true
5 max 10 // 10
5 min 10 // 5
5 sort 3 // (3, 5)Extensions for types with Semigroup/Monoid instances.
// Available via import scalaz.syntax.semigroup._ or import scalaz.Scalaz._
implicit class SemigroupOps[A](self: A)(implicit A: Semigroup[A]) {
/** Semigroup append */
def |+|(other: => A): A = A.append(self, other)
/** Multiply (repeat operation) */
def multiply1(n: Int): A = A.multiply1(self, n)
}
// Available via import scalaz.syntax.monoid._ or import scalaz.Scalaz._
implicit class MonoidOps[A](self: A)(implicit A: Monoid[A]) {
/** Check if zero */
def isEmpty: Boolean = A.isMEmpty(self)
/** Multiply with zero handling */
def multiply(n: Int): A = A.multiply(self, n)
}
// Monoid zero
implicit class MonoidZeroOps[A](implicit A: Monoid[A]) {
def mzero: A = A.zero
}Usage Examples:
import scalaz._
import scalaz.syntax.monoid._
import scalaz.std.string._
import scalaz.std.list._
"Hello" |+| " " |+| "World" // "Hello World"
List(1, 2) |+| List(3, 4) // List(1, 2, 3, 4)
List(1, 2).multiply(3) // List(1, 2, 1, 2, 1, 2)
mzero[String] // ""Extensions for types with Show instances.
// Available via import scalaz.syntax.show._ or import scalaz.Scalaz._
implicit class ShowOps[A](self: A)(implicit A: Show[A]) {
/** Convert to string */
def shows: String = A.shows(self)
/** Convert to Cord */
def show: Cord = A.show(self)
/** Print to console */
def println: Unit = Predef.println(shows)
/** Print without newline */
def print: Unit = Predef.print(shows)
}Usage Examples:
import scalaz._
import scalaz.syntax.show._
import scalaz.std.anyVal._
42.shows // "42"
42.println // Prints: 42
// Custom Show instances provide better output than toString
case class Person(name: String, age: Int)
implicit val personShow: Show[Person] = Show.shows(p => s"${p.name}(${p.age})")
Person("John", 30).shows // "John(30)"Extensions for working with Validation types.
// Available via import scalaz.syntax.validation._ or import scalaz.Scalaz._
implicit class ValidationOps[A](self: A) {
/** Create success validation */
def success[E]: Validation[E, A] = Success(self)
/** Create success validation with NonEmptyList error type */
def successNel[E]: ValidationNel[E, A] = Success(self)
}
implicit class ValidationErrorOps[E](self: E) {
/** Create failure validation */
def failure[A]: Validation[E, A] = Failure(self)
/** Create failure validation with NonEmptyList */
def failureNel[A]: ValidationNel[E, A] = Failure(NonEmptyList(self))
}Usage Examples:
import scalaz._
import scalaz.syntax.validation._
import scalaz.syntax.applicative._
// Creating validations
val valid = "John".success[String]
val invalid = "Empty name".failure[String]
// Error accumulation
val result = (
"John".successNel[String] |@|
"Invalid age".failureNel[String] |@|
"john@example.com".successNel[String]
) { (name, age, email) => User(name, age, email) }Extensions for Either and Disjunction (/) types.
// Available via import scalaz.syntax.either._ or import scalaz.Scalaz._
implicit class EitherOps[A](self: A) {
/** Create left disjunction */
def left[B]: A \/ B = -\/(self)
/** Create right disjunction */
def right[B]: B \/ A = \/-(self)
}
implicit class DisjunctionOps[A, B](self: A \/ B) {
/** Alias for map */
def \/[C](f: B => C): A \/ C = self.map(f)
/** Get right or default */
def |(default: => B): B = self.getOrElse(default)
}Usage Examples:
import scalaz._
import scalaz.syntax.either._
val success = 42.right[String] // String \/ Int = \/-(42)
val failure = "error".left[Int] // String \/ Int = -\/("error")
success | 0 // 42
failure | 0 // 0Extensions for types with MonadPlus instances.
// Available via import scalaz.syntax.monadPlus._ or import scalaz.Scalaz._
implicit class MonadPlusOps[F[_], A](self: F[A])(implicit F: MonadPlus[F]) {
/** Filter with predicate */
def filter(p: A => Boolean): F[A] = F.filter(self)(p)
/** Alternative operator */
def <+>(other: => F[A]): F[A] = F.plus(self, other)
/** Return this if non-empty, otherwise alternative */
def orElse(alternative: => F[A]): F[A] = F.plus(self, alternative)
}
// Empty values
implicit class MonadPlusEmptyOps[F[_]](implicit F: MonadPlus[F]) {
def empty[A]: F[A] = F.empty[A]
}Usage Examples:
import scalaz._
import scalaz.syntax.monadPlus._
import scalaz.std.list._
List(1, 2, 3, 4).filter(_ % 2 == 0) // List(2, 4)
List(1, 2) <+> List(3, 4) // List(1, 2, 3, 4)
List.empty[Int] orElse List(1, 2) // List(1, 2)// Import all syntax extensions
import scalaz._
import Scalaz._
// Or import syntax package
import scalaz.syntax.all._// Import specific syntax
import scalaz.syntax.functor._ // Functor operations
import scalaz.syntax.applicative._ // Applicative operations
import scalaz.syntax.monad._ // Monad operations
import scalaz.syntax.foldable._ // Foldable operations
import scalaz.syntax.traverse._ // Traverse operations
import scalaz.syntax.equal._ // Equal operations
import scalaz.syntax.order._ // Order operations
import scalaz.syntax.semigroup._ // Semigroup operations
import scalaz.syntax.monoid._ // Monoid operations
import scalaz.syntax.show._ // Show operations
import scalaz.syntax.validation._ // Validation operations
import scalaz.syntax.either._ // Either/Disjunction operations// Common combination for everyday functional programming
import scalaz.{Applicative, Functor, Monad, Equal, Show, \/, ValidationNel}
import scalaz.syntax.applicative._
import scalaz.syntax.functor._
import scalaz.syntax.monad._
import scalaz.syntax.equal._
import scalaz.syntax.validation._
import scalaz.std.option._
import scalaz.std.list._
import scalaz.std.string._Usage Examples:
import scalaz._
import Scalaz._
// All syntax available
val result = List(1, 2, 3)
.map(_ * 2) // Functor syntax
.filter(_ > 2) // MonadPlus syntax
.foldMap(_.toString) // Foldable syntax
val validation = (
"John".successNel[String] |@| // Validation syntax
25.successNel[String] |@| // Applicative syntax
"john@example.com".successNel[String]
) { User(_, _, _) }
val comparison = 1 === 1 && 5 > 3 // Equal and Order syntax
val combined = "Hello" |+| " World" // Monoid syntaxInstall with Tessl CLI
npx tessl i tessl/maven-org-scalaz--scalaz-core-sjs1-2-13