typelevel / scalaz-contrib

Interoperability libraries & additional data structures and instances for Scalaz
http://typelevel.org
MIT License
54 stars 16 forks source link

scalaz-contrib

Interoperability libraries & additional data structures and instances for Scalaz

Build Status

Usage

This library is currently available for Scala 2.11 only. For 2.10 builds, use version 0.1.5.

To use the latest version, include the following in your build.sbt:

libraryDependencies ++= Seq(
  "org.typelevel" %% "scalaz-contrib-210"        % "0.2",
  "org.typelevel" %% "scalaz-contrib-validation" % "0.2",
  "org.typelevel" %% "scalaz-contrib-undo"       % "0.2",
  // currently unavailable because there's no 2.11 build of Lift yet
  // "org.typelevel" %% "scalaz-lift"               % "0.2",
  "org.typelevel" %% "scalaz-nscala-time"        % "0.2",
  "org.typelevel" %% "scalaz-spire"              % "0.2"
)

For the in-progress features, use the following:

resolvers += Resolver.sonatypeRepo("snapshots")

and depend on version 0.3-SNAPSHOT instead.

Examples

Scala 2.10+

You can now use type class instances for new data types in the standard library:

scala> import scalaz._
import scalaz._

scala> import scalaz.contrib.std.utilTry._
import scalaz.contrib.std.utilTry._

scala> Monad[scala.util.Try]
res1: scalaz.Monad[scala.util.Try] = scalaz.contrib.std.TryInstances1$$anon$1@19ae3dd5

The instance for Scala's Future is in scalaz proper. Try remains here.

Validation DSL

There are a couple of useful validators and converters, as well as a DSL for checking and transforming values.

import scalaz.contrib.Checker
import scalaz.contrib.validator.all._, scalaz.contrib.converter.all._
import scalaz.std.list._

val c = Checker.check("2012-12-20".toList)

scala> c.checkThat(notEmpty("must be non-empty")(_)).
     |   map(_.mkString("")).
     |   convertTo(date("yyyy-MM-dd", "must be a valid date")).
     |   toValidation
res0: Validation[NonEmptyList[String],Date] = Success(Thu Dec 20 00:00:00 CET 2012)

scala> c.checkThat(notEmpty("must be non-empty")(_)).
     |   map(_.mkString("")).
     |   convertTo(uuid("must be a valid UUID")).
     |   toValidation
res1: Validation[NonEmptyList[String],Date] = Failure(NonEmptyList(must be a valid UUID))

Undo

Originally by Gerolf Seitz (@gseitz).

import scalaz.contrib.undo.UndoT
import UndoT._
import scalaz.std.option._

val result = for {
  one           <- hput[Option, Int](1)
  two           <- hput[Option, Int](2)
  three         <- hput[Option, Int](3)
  twoAgain      <- undo[Option, Int]
  four          <- hput[Option, Int](4)
  twoAgainAgain <- undo[Option, Int]
  fourAgain     <- redo[Option, Int]
} yield ()

scala> result.exec(1)
res0: Option[Int] = Some(4)

Library bindings

This project provides bindings (instances) for the following libraries:

spire

Spire provides powerful abstractions for numeric programming in Scala, including a full-stack hierarchy of algebraic type classes such as Semigroup, Monoid, and Ring. Scalaz only has the former two, but instead lots of instances. This library provides mappings between type classes where it makes sense.

There are two modes of conversion, manual and automatic:

It is possible (but not recommended) to enable both modes.

To understand which conversions "make sense", consider the kinds of type classes offered by scalaz and spire:

Thus, in manual mode, the following conversions are available:

These operations are also available in automatic mode, without the need to call asXY.

The other direction is for free since the two-operator classes extend the one-operator classes. This operation is not available in automatic mode, since there is no guarantee that two independent scalaz instances obey the necessary laws to form a two-operator class.

Of course, the above mentioned conversions also work for Monoid and Rig.