Name: scalaz
Owner: Scalaz
Description: An extension to the core Scala library for functional programming.
Created: 2010-01-16 06:18:51.0
Updated: 2018-01-17 17:12:02.0
Pushed: 2018-01-18 17:22:09.0
Homepage: https://scalaz.github.io/scalaz/#scaladoc
Size: 96428
Language: Scala
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
Scalaz is a Scala library for functional programming.
It provides purely functional data structures to complement those from the Scala standard library.
It defines a set of foundational type classes (e.g. Functor
, Monad
) and corresponding instances for
a large number of data structures.
The current stable version is 7.2.19, which is cross-built against Scala 2.10.x, 2.11.x and 2.12.x.
If you're using SBT, add the following line to your build file:
aryDependencies += "org.scalaz" %% "scalaz-core" % "7.2.19"
For Maven and other build tools, you can visit search.maven.org. (This search will also list all available modules of scalaz.)
To get sample configurations, click on the version of the module you are interested in.
You can also find direct download links at the bottom of that page. Choose the file ending in 7.2.19.jar
.
rt scalaz._
rt std.option._, std.list._ // functions and type class instances for Option and List
a> Apply[Option].apply2(some(1), some(2))((a, b) => a + b)
: Option[Int] = Some(3)
a> Traverse[List].traverse(List(1, 2, 3))(i => some(i))
: Option[List[Int]] = Some(List(1, 2, 3))
Use of the Ops
classes, defined under scalaz.syntax
.
rt scalaz._
rt std.list._ // type class instances for List
rt syntax.bind._ // syntax for the Bind type class (and its parents)
a> List(List(1)).join
: List[Int] = List(1)
a> List(true, false).ifM(List(0, 1), List(2, 3))
: List[Int] = List(0, 1, 2, 3)
We've gone to great lengths to give you an a-la-carte importing experience, but if you prefer an all-you-can-eat buffet, you're in luck:
rt scalaz._
rt Scalaz._
a> NonEmptyList(1, 2, 3).cojoin
: scalaz.NonEmptyList[scalaz.NonEmptyList[Int]] = NonEmptyList(NonEmptyList(1, 2, 3), NonEmptyList(2, 3), NonEmptyList(3))
a> 1.node(2.leaf, 3.node(4.leaf))
: scalaz.Tree[Int] = <tree>
a> List(some(1), none).suml
: Option[Int] = Some(1)
Let the types speak for themselves via the Scalaz Scaladocs!
The examples module contains some snippets of Scalaz usage.
The wiki contains release and migration information.
Talk with us by joining IRC: irc.freenode.net channel #scalaz, or join the Scalaz mailing list on Google Groups.
The typelevel blog has some great posts such as Towards Scalaz by Adelbert Chang.
Learning Scalaz is a great series of blog posts by Eugene Yokota. Thanks, Eugene!
Scalaz 7 represents a major reorganization of the library. We have taken a fresh look at the challenges of encoding type classes in Scala, in particular at when and how to employ the implicit scope.
scalaz.{concurrent, effect, iteratee}
split to separate sub-projects; scalaz.{http, geo}
dropped.scalaz.std
, and instances for
Scalaz data types are defined in the companion object for those types. An instance definition
can provide multiple type classes in a single place, which was not always possible in Scalaz 6.Monoid[(A, B)]
)scalaz.syntax
, and can be imported selectively, and need not
be used at all.Identity
, MA
, or MAB
.Scalaz has been modularised.
implicit conversions / syntax to access these.
bar[M[_]: Functor] = ()
foo[M[_]: Monad] = bar[M] // Monad[M] is a subtype of Functor[M]
scalaz.std
, and must be imported. These instances are defined in traits which will be
mixed together into an object for importing en-masse, if desired.Here is an instance definition for Option
. Notice that the method map
has been overriden.
plicit val option = new Traverse[Option] with MonadPlus[Option] {
def point[A](a: => A) = Some(a)
def bind[A, B](fa: Option[A])(f: A => Option[B]): Option[B] = fa flatMap f
override def map[A, B](fa: Option[A])(f: A => B): Option[B] = fa map f
def traverseImpl[F[_], A, B](fa: Option[A])(f: A => F[B])(implicit F: Applicative[F]) =
fa map (a => F.map(f(a))(Some(_): Option[B])) getOrElse F.point(None)
def empty[A]: Option[A] = None
def plus[A](a: Option[A], b: => Option[A]) = a orElse b
def foldR[A, B](fa: Option[A], z: B)(f: (A) => (=> B) => B): B = fa match {
case Some(a) => f(a)(z)
case None => z
}
To use this, one would:
rt scalaz.std.option.optionInstance
r, importing all instances en-masse
mport scalaz.Scalaz._
M = Monad[Option]
oi: Option[Int] = M.point(0)
We co-opt the term syntax to refer to the way we allow the functionality of Scalaz to be
called in the object.method(args)
form, which can be easier to read, and, given that type inference
in Scala flows from left-to-right, can require fewer type annotations.
Identity
, MA
, or MAB
from Scalaz 6.scalaz.syntax
.Applicative
will also provide the syntax for Apply
and Functor
.Syntax can be imported in two ways. Firstly, the syntax specialized for a particular instance of a type class can be imported directly from the instance itself.
mport the type class instance
rt scalaz.std.option.optionInstance
mport the implicit conversions to `MonadOps[Option, A]`, `BindOps[Option, A]`, ...
rt optionInstance.monadSyntax._
oi: Option[Option[Int]] = Some(Some(1))
xpands to: `ToBindOps(io).join`
oin
Alternatively, the syntax can be imported for a particular type class.
mport the type class instance
rt scalaz.std.option.optionInstance
mport the implicit conversions to `MonadOps[F, A]`, `BindOps[F, A]`, ...
rt scalaz.syntax.monad._
oi: Option[Option[Int]] = Some(Some(1))
xpands to: ToBindOps(io).join
oin
For some degree of backwards compatibility with Scalaz 6, the über-import of import scalaz.Scalaz._
will import all implicit conversions that provide syntax (as well as type class instances and other
functions). However, we recommend to review usage of this and replace with more focussed imports.
Type classes should be directly usable, without first needing to trigger implicit conversions. This might be desirable to reduce the runtime or cognitive overhead of the pimped types, or to define your own pimped types with a syntax of your choosing.
apply
method to obtain an instance of the type class.// Equivalent to `implicitly[Monad[Option]]`
val O = Monad[Option]
// `bind` is defined with two parameter sections, so that the type of `x` is inferred as `Int`.
O.bind(Some(1))(x => Some(x * 2))
def plus(a: Int, b: Int) = a + b
// `Apply#lift2` is a function derived from `Apply#ap`.
val plusOpt = O.lift2(plus)
Type class instances may depend on other instances. In simple cases, this is as straightforward as adding an implicit parameter (or, equivalently, a context bound), to the implicit method.
plicit def optionMonoid[A: Semigroup]: Monoid[Option[A]] = new Monoid[Option[A]] {
def append(f1: Option[A], f2: => Option[A]): Option[A] = (f1, f2) match {
case (Some(a1), Some(a2)) => Some(Semigroup[A].append(a1, a2))
case (Some(a1), None) => f1
case (None, Some(a2)) => f2
case (None, None) => None
}
def zero: Option[A] = None
Type class instances for 'transformers', such as OptionT
, present a more subtle challenge. OptionT[F, A]
is a wrapper for a value of type F[Option[A]]
. It allows us to write:
ot = OptionT(List(Some(1), None))
ap((a: Int) => a * 2) // OptionT(List(Some(2), None))
The method OptionT#map
requires an implicit parameter of type Functor[F]
, whereas OptionT#flatMap
requires one of type Monad[F]
. The capabilities of OptionT
increase with those of F
. We need to encode
this into the type class instances for [a]OptionT[F[A]]
.
This is done with a hierarchy of type class implementation traits and a corresponding set of prioritized implicit methods.
In case of ambiguous implicits, Scala will favour one defined in a sub-class of the other. This is to avoid ambiguity when in cases like the following:
OptionTList[A] = OptionT[List[A]]
icitly[Functor[OptionTList]]
andidates:
. OptionT.OptionTFunctor[List](implicitly[Functor[List]])
. OptionT.OptionTMonad[List](implicitly[Functor[List]])
2 is defined in a subclass of the enclosing class of #1, so #2 is preferred.
A stronger emphasis has been placed on transformer data structures (aka Monad Transformers). For example State
is now
a type alias for StateT[Id, A, B]
.
Id
is defined in the scalaz
package object as:
Id[A] = A
Documentation for contributors
Support for Scalaz development is provided by Jetbrains.
Thanks to Mark Harrah and the sbt contributors for providing our build tool.