scalaVersion := "2.10.0-M6"
resolvers += "Typesafe Snapshots" at "http://repo.typesafe.com/typesafe/snapshots/"
libraryDependencies ++= Seq(
"org.scalaz" %% "scalaz-core" % "7.0.0-M1"
)
scalacOptions += "-feature"
initialCommands in console := "import scalaz._, Scalaz._"
def double[A](a: A)(implicit s: Semigroup[A]) = s.append(a, a)
double(2) assert_=== 4
double("2") assert_=== "22"
case class Point(x: Int, y: Int) {
def +(p: Point) = Point(x + p.x, y + p.y)
}
object Point {
implicit object PointInstance extends Semigroup[Point] {
def append(p1: Point, p2: => Point) = p1 + p2
}
}
assert(double(Point(1, 2)) == Point(2, 4))
object Point {
implicit object PointInstance extends Show[Point] with Semigroup[Point] {
def show(p: Point) = p.toString.toList
def append(p1: Point, p2: => Point) = p1 + p2
}
}
case class Rational(n: Int, d: Int) {
def +(r: Rational) = Rational(n * r.d + r.n * d, d * r.d)
override def toString = s"$n/$d"
}
object vector {
def VectorShow[A]: Show[Vector[A]]
}
import vector._
assert(implicitly[Show[Vector[Int]]].shows(Vector(1)) == "Vector(1)")
assert(implicitly[Show[Vector[String]]].shows(Vector("geso")) == "Vector(geso)")
assert(implicitly[Show[Rational]].shows(Rational(1, 2)) == "1/2")
assert(implicitly[Semigroup[Rational]].append(Rational(1, 2), Rational(1, 2)) == Rational(4, 4))
def quote[A](a: A)(implicit s: Show[A]) = s.show(a).mkString("'", "", "'")
def quote[A: Show](a: A) = implicitly[Show[A]].show(a).mkString("'", "", "'")
quote("geso") assert_=== "'geso'"
quote(List(1, 2, 3)) assert_=== "'[1,2,3]'"
scalaz
scalaz.std
scalaz.syntax
Instances
Functions
Ops
Syntax
def double[A: Semigroup](a: A) = Semigroup[A].append(a, a)
implicit lazy val PointShow = Show.showA[Point]
implicit lazy val PointEqual = Equal.equalA[Point]
def double[A: Semigroup](a: A) = a |+| a
def double[A: Semigroup](a: A) = ToSemigroupOps(a) |+| a
def quote[A: Show](a: A) = Show[A].show(a).mkString("'", "", "'")
def quote[A: Show](a: A) = a.show.mkString("'", "", "'")
case class Rational(n: Int, d: Int) {
def +(r: Rational) = Rational(n * r.d + r.n * d, d * r.d)
}
object Rational {
implicit object RationalInstance extends Monoid[Rational] {
def zero = Rational(0, 1)
def append(r1: Rational, r2: => Rational) = r1 + r2
}
}
mzero[Int] assert_=== 0
mzero[Option[String]] assert_=== None
mzero[Rational] assert_=== Rational(0, 1)
val a = 1
mzero[Int] |+| a assert_=== a
a |+| mzero[Int] assert_=== a
Monoid.replicate[List, Int](0)(3, 1 +) assert_=== List(0, 1, 2)
Monoid.unfold[List, List[Int], Int](List(1, 2, 3)) {
case Nil => None
case x :: xs => Some(x * 2 -> xs)
} assert_=== List(2, 4, 6)
def evens(n: Int): List[Int]
def encode(n: Int): List[Int]
evens(5) assert_=== List(0, 2, 4, 6, 8)
encode(13) assert_=== List(1, 0, 1, 1)
object Rational {
implicit object RationalInstance extends Order[Rational] with Show[Rational] with Group[Rational] {
def zero = Rational(0, 1)
def append(r1: Rational, r2: => Rational) = r1 + r2
def inverse(r: Rational) = Rational(-r.n, r.d)
}
}
1.inverse assert_=== -1
Rational(1, 2).inverse assert_=== Rational(-1, 2)
List(1, 2) |+| List(3, 4) assert_=== List(1, 2, 3, 4)
List(1, 2) <+> List(3, 4) assert_=== List(1, 2, 3, 4)
Option(1) |+| Option(1) assert_=== Option(2)
Option(1) <+> Option(1) assert_=== Option(1)
object vector {
implicit object VectorInstance extends PlusEmpty[Vector] {
def empty[A] = Vector.empty[A]
def plus[A](v1: Vector[A], v2: => Vector[A]) = v1 ++ v2
}
}
import vector._
assert(Vector(1, 2) <+> Vector(3, 4) == Vector(1, 2, 3, 4))
("geso": Id[String]) assert_=== "geso"
1.some assert_=== Some(1)
none[Int] assert_=== None
assert(1.right[String] === Right(1))
assert("geso".left[Int] === Left("geso"))
1 |> (1 +) assert_=== 2
"geso" |> (_.size) assert_=== 4
0 |> Show[Int].shows assert_=== "0"
object Point {
implicit object PointInstance extends Equal[Point] {
def equal(p1: Point, p2: Point) = p1 == p2
}
}
assert(Point(2, 3) === Point(2, 3))
assert(Point(2, 3) =/= Point(3, 5))
1 == "geso"
/* 1 === "geso" */ // compile error
1 + 1.5
/* 1 |+| 1.5 */ // compile error
object Rational {
implicit object RationalInstance extends Order[Rational] {
def order(r1: Rational, r2: Rational) = r1.n * r2.d -> r2.n * r1.d match {
case (m, n) if m == n => Ordering.EQ
case (m, n) if m < n => Ordering.LT
case (m, n) if m > n => Ordering.GT
}
}
}
assert(Rational(1, 2) === Rational(1, 2))
assert(Rational(1, 2) < Rational(3, 4))
assert(Rational(5, 2) >= Rational(5, 3))
mzero[Ordering] assert_=== Ordering.EQ
(Ordering.EQ: Ordering) |+| Ordering.LT assert_=== Ordering.LT
(Ordering.GT: Ordering) |+| Ordering.LT assert_=== Ordering.GT
(Ordering.GT: Ordering) |+| Ordering.EQ assert_=== Ordering.GT
case class Person(name: String, age: Int, height: Int)
object Person {
implicit object PersonInstance extends Show[Person] with Order[Person] {
def show(p: Person) = p.toString.toList
def order(p1: Person, p2: Person) =
p1.age ?|? p2.age |+| p1.height ?|? p2.height
}
}
val miku = Person("miku", 16, 158)
val rin = Person("rin", 14, 152)
val len = Person("len", 14, 156)
List(miku, rin, len) sorted Order[Person].toScalaOrdering assert_=== List(rin, len, miku)
以下のクラスに対するOrderのインスタンス
case class Student(name: String, grade: Int, birthday: Date)
val format = new java.text.SimpleDateFormat("yyyy MM dd")
val akari = Student("akari", 1, format.parse("1995 07 24"))
val kyoko = Student("kyoko", 2, format.parse("1995 03 28"))
val yui = Student("yui", 2, format.parse("1994 04 22"))
val chinatsu = Student("chinatsu", 1, format.parse("1995 11 06"))
List(akari, kyoko, yui, chinatsu) sorted Order[Student].toScalaOrdering assert_=== List(akari, chinatsu, yui, kyoko)
object Rational {
implicit object RationalInstance extends Enum[Rational] {
def order(r1: Rational, r2: Rational) = r1.n * r2.d -> r2.n * r1.d match {
case (m, n) if m == n => Ordering.EQ
case (m, n) if m < n => Ordering.LT
case (m, n) if m > n => Ordering.GT
}
def succ(r: Rational) = r.copy(n = r.n + r.d)
def pred(r: Rational) = r.copy(n = r.n - r.d)
}
}
1.succ assert_=== 2
Rational(1, 2).succ assert_=== Rational(3, 2)
'b'.pred assert_=== 'a'
Rational(1, 2).pred assert_=== Rational(-1, 2)
sealed trait Author
sealed trait Title
case class Book(title: String @@ Title, author: String @@ Author)
val book = Book(Tag("Programming in Scala"), Tag("Martin Odersky"))
/* book.copy(title = book.author) */ // compile error
import scalaz.Tags._
3 |+| 3 assert_=== 6
(Multiplication(3) |+| Multiplication(3): Int) assert_=== 9
(Conjunction(true) |+| Conjunction(false): Boolean) assert_=== false
(Disjunction(true) |+| Disjunction(false): Boolean) assert_=== true
import scalaz.Dual._
(Dual("hello") |+| Dual("world"): String) assert_=== "worldhello"
def size[A](a: A)(implicit ev: A Contains t[Int]#t[String]#t[List[_]]) = a match {
case i: Int => i
case s: String => s.length
case l: List[_] => l.size
}
size(1) assert_=== 1
size("geso") assert_=== 4
size(List(1, 2, 3)) assert_=== 3
/* size(1L) */ // compile error
import scala.language.higherKinds
def triple[F[_]: Plus, A](fa: F[A]) = fa <+> fa <+> fa
triple(Option(1)) assert_=== Option(1)
triple(List(1)) assert_=== List(1, 1, 1)
object vector {
implicit object VectorInstance extends Functor[Vector] {
def map[A, B](v: Vector[A])(f: A => B) = v map f
}
}
def fdouble[F[_]: Functor, A: Semigroup](fa: F[A]) = fa.map(a => a |+| a)
fdouble(List(1, 2, 3)) assert_=== List(2, 4, 6)
fdouble("geso".some) assert_=== Some("gesogeso")
import vector._
fdouble(Vector(1.2, 2.1)) assert_=== Vector(2.4, 4.2)
val fa = List(1, 2)
lazy val f: Int => Int = _ + 2
lazy val g: Int => Int = _ * 2
fa map (x => x) assert_=== fa
fa map f map g assert_=== (fa map g <<< f)
object vector {
implicit object VectorInstance extends Pointed[Vector] {
def map[A, B](v: Vector[A])(f: A => B) = v map f
def point[A](a: => A) = Vector(a)
}
}
Pointed[List].point(1) assert_=== List(1)
Pointed[Option].point(1) assert_=== Some(1)
import vector._
Pointed[Vector].point(1) assert_=== Vector(1)
assert(Functor[({ type F[A] = Either[String, A] })#F].map(Right(1))(_.succ) === Right(2))
assert(Pointed[({ type F[A] = Either[String, A] })#F].point(1) === Right(1))
object vector {
implicit object VectorInstance extends Apply[Vector] {
def map[A, B](v: Vector[A])(f: A => B) = v map f
def ap[A, B](va: => Vector[A])(vab: => Vector[A => B]) = vab flatMap (va map _)
}
}
Option(0) <*> Option(Enum[Int].succ _) assert_=== Option(1)
List(1, 2, 3) <*> PlusEmpty[List].empty[Int => Int] assert_=== Nil
import vector._
Vector(1, 2) <*> Vector(Enum[Int].succ _, Enum[Int].pred _) assert_=== Vector(2, 3, 0, 1)
object vector {
implicit object VectorInstance extends Applicative[Vector] {
def point[A](a: => A) = Vector(a)
def ap[A, B](va: => Vector[A])(vab: => Vector[A => B]) = vab flatMap (va map _)
}
}
val a = 0
val fa = Option(a)
lazy val fab: Option[Int => String] = Option(_.toString)
lazy val fbc: Option[String => Int] = Option(_.size)
fa <*> ((a: Int) => a).point[Option] assert_=== fa
fa <*> fab <*> fbc assert_=== fa <*> (fab <*> (fbc <*> (((bc: String => Int) => (ab: Int => String) => bc compose ab).point[Option])))
a.point[Option] <*> ab.point[Option] assert_=== ab(a).point[Option]
a.point[Option] <*> fab assert_=== fab <*> ((f: Int => String) => f(a)).point[Option]
def append3[F[_]: Apply, A: Semigroup](fa: F[A], fb: F[A], fc: F[A]) =
(fa |@| fb |@| fc)(_ |+| _ |+| _)
append3(Option(1), Option(2), Option(3)) assert_=== Option(6)
append3(Option(1), None, Option(3)) assert_=== None
append3(List(1), List(1, 2), List(1, 2, 3)) assert_=== List(3, 4, 5, 4, 5, 6)
case class User(id: String, pass: String)
def user(m: Map[String, String]): Option[User]
user(Map("id" -> "halcat0x15a", "pass" -> "gesogeso")) assert_=== Some(User("halcat0x15a", "gesogeso"))
user(Map.empty) assert_=== None
object vector {
implicit object VectorInstance extends Bind[Vector] {
def map[A, B](v: Vector[A])(f: A => B) = v map f
def bind[A, B](v: Vector[A])(f: A => Vector[B]) = v flatMap f
}
}
def append3[F[_]: Bind, A: Semigroup](fa: F[A], fb: F[A], fc: F[A]) =
for {
a <- fa
b <- fb
c <- fc
} yield a |+| b |+| c
(for (a <- List(1, 2)) yield a + 1) assert_=== List(1, 2).map(a => a + 1)
(for (a <- Option(1); b <- Option(2)) yield a + b) assert_=== Option(1).flatMap(a => Option(2).map(b => a + b))
(for (a <- List(1, 2) if a % 2 == 0) yield a) assert_=== List(1, 2).filter(a => a % 2 == 0)
object vector {
implicit object VectorInstance extends Monad[Vector] {
def point[A](a: => A) = Vector(a)
def bind[A, B](v: Vector[A])(f: A => Vector[B]) = v flatMap f
}
}
import scala.util.control.Exception._
val a = 1
val fa = Option(a)
lazy val f: Int => Option[String] = _.toString |> Option.apply
lazy val g: String => Option[Int] = allCatch opt _.toInt
(fa >>= (_.point[Option])) assert_=== fa
(a.point[Option] >>= f) assert_=== f(a)
(fa >>= f >>= g) assert_=== (fa >>= (a => f(a) >>= g))
object vector {
implicit object VectorInstance extends ApplicativePlus[Vector] {
def empty[A] = Vector.empty[A]
def plus[A](v1: Vector[A], v2: => Vector[A]) = v1 ++ v2
def point[A](a: => A) = Vector(a)
def ap[A, B](va: => Vector[A])(vab: => Vector[A => B]) = vab flatMap (va map _)
}
}
object vector {
implicit object VectorInstance extends MonadPlus[Vector] {
def empty[A] = Vector.empty[A]
def plus[A](v1: Vector[A], v2: => Vector[A]) = v1 ++ v2
def point[A](a: => A) = Vector(a)
def bind[A, B](v: Vector[A])(f: A => Vector[B]) = v flatMap f
}
}
def evens[F[_]: MonadPlus](f: F[Int]) = f filter (_ % 2 === 0)
evens(List(1, 2, 3)) assert_=== List(2)
evens(Option(1)) assert_=== None
import vector._
evens(Vector(1, 2, 3)) assert_=== Vector(2)