Permalink
Browse files

initial commit

  • Loading branch information...
non committed Jan 28, 2015
0 parents commit 9d1837e20a89c99c174723a2f112d84507b9ebdb
Showing with 1,399 additions and 0 deletions.
  1. +11 −0 .gitignore
  2. +2 −0 README.md
  3. +62 −0 build.sbt
  4. +1 −0 core/build.sbt
  5. +17 −0 core/src/main/scala/cats/Applicative.scala
  6. +16 −0 core/src/main/scala/cats/Apply.scala
  7. +17 −0 core/src/main/scala/cats/Bijection.scala
  8. +5 −0 core/src/main/scala/cats/Bimonad.scala
  9. +10 −0 core/src/main/scala/cats/CoFlatMap.scala
  10. +7 −0 core/src/main/scala/cats/Comonad.scala
  11. +13 −0 core/src/main/scala/cats/FlatMap.scala
  12. +30 −0 core/src/main/scala/cats/Foldable.scala
  13. +16 −0 core/src/main/scala/cats/Functor.scala
  14. +11 −0 core/src/main/scala/cats/Id.scala
  15. +5 −0 core/src/main/scala/cats/Monad.scala
  16. +22 −0 core/src/main/scala/cats/Traverse.scala
  17. +24 −0 core/src/main/scala/cats/arrow/Arrow.scala
  18. +25 −0 core/src/main/scala/cats/arrow/Category.scala
  19. +25 −0 core/src/main/scala/cats/arrow/Cokleisli.scala
  20. +25 −0 core/src/main/scala/cats/arrow/Compose.scala
  21. +55 −0 core/src/main/scala/cats/arrow/Kleisli.scala
  22. +19 −0 core/src/main/scala/cats/arrow/MonoidK.scala
  23. +10 −0 core/src/main/scala/cats/arrow/NaturalTransformation.scala
  24. +23 −0 core/src/main/scala/cats/arrow/SemigroupK.scala
  25. +10 −0 core/src/main/scala/cats/arrow/Split.scala
  26. +255 −0 core/src/main/scala/cats/free/Coyoneda.scala
  27. +454 −0 core/src/main/scala/cats/free/Free.scala
  28. +58 −0 core/src/main/scala/cats/free/Yoneda.scala
  29. +10 −0 core/src/main/scala/cats/functor/Bifunctor.scala
  30. +9 −0 core/src/main/scala/cats/functor/Contravariant.scala
  31. +8 −0 core/src/main/scala/cats/functor/Invariant.scala
  32. +34 −0 core/src/main/scala/cats/functor/Profunctor.scala
  33. +11 −0 core/src/main/scala/cats/functor/Strong.scala
  34. +14 −0 core/src/main/scala/cats/package.scala
  35. +6 −0 laws/build.sbt
  36. +1 −0 project/build.properties
  37. +62 −0 project/build.scala
  38. +7 −0 project/plugins.sbt
  39. +7 −0 tests/build.sbt
  40. +2 −0 version.sbt
@@ -0,0 +1,11 @@
project/boot
target
.ensime
.ensime_lucene
TAGS
\#*#
*~
.#*
.lib
.history
.*.swp
@@ -0,0 +1,2 @@
# cats
@@ -0,0 +1,62 @@
organization in ThisBuild := "org.spire-math"
homepage in ThisBuild := Some(url("http://github.com/non/cats"))
licenses in ThisBuild := Seq("MIT" -> url("http://opensource.org/licenses/MIT"))
scalaVersion in ThisBuild := "2.11.5"
crossScalaVersions in ThisBuild := Seq("2.10.4", "2.11.5")
// comprehensive tpolecat-recommended scalac options
scalacOptions in ThisBuild ++= (
"-deprecation" ::
"-encoding" :: "UTF-8" ::
"-feature" ::
"-language:existentials" ::
"-language:higherKinds" ::
"-language:implicitConversions" ::
"-unchecked" ::
"-Xfatal-warnings" ::
"-Xlint" ::
"-Yno-adapted-args" ::
"-Ywarn-dead-code" ::
"-Ywarn-numeric-widen" ::
"-Ywarn-value-discard" ::
"-Xfuture" ::
Nil
)
resolvers in ThisBuild +=
"bintray/non" at "http://dl.bintray.com/non/maven"
libraryDependencies in ThisBuild ++=
"org.spire-math" %% "algebra" % "0.2.0-SNAPSHOT" ::
"org.typelevel" %% "machinist" % "0.3.0" ::
compilerPlugin("org.spire-math" %% "kind-projector" % "0.5.2") ::
"com.github.mpilquist" %% "simulacrum" % "0.1.0" ::
compilerPlugin("org.scalamacros" % "paradise" % "2.0.1" cross CrossVersion.full) ::
Nil
publishMavenStyle in ThisBuild := true
publishArtifact in ThisBuild in Test := false
pomIncludeRepository in ThisBuild := { _ => false }
publishTo in ThisBuild <<= version { (v: String) =>
val nexus = "https://oss.sonatype.org/"
if (v.trim.endsWith("SNAPSHOT"))
Some("snapshots" at nexus + "content/repositories/snapshots")
else
Some("releases" at nexus + "service/local/staging/deploy/maven2")
}
pomExtra in ThisBuild := (
<scm>
<url>git@github.com:non/cats.git</url>
<connection>scm:git:git@github.com:non/cats.git</connection>
</scm>
<developers>
<developer>
<id>non</id>
<name>Erik Osheim</name>
<url>http://github.com/non/</url>
</developer>
</developers>
)
@@ -0,0 +1 @@
name := "cats"
@@ -0,0 +1,17 @@
package cats
import simulacrum._
/**
* Applicative functor.
*
* Must obey the following laws:
* - apply(fa)(pure(a => a)) = fa
* - apply(pure(a))(pure(f)) = pure(f(a))
* - apply(pure(a))(ff) = apply(ff)(pure(f => f(a)))
* - map(fa)(f) = apply(fa)(pure(f))
*/
@typeclass trait Applicative[F[_]] extends Apply[F] {
def pure[A](x: A): F[A]
override def map[A, B](fa: F[A])(f: A => B): F[B] = apply(fa)(pure(f))
}
@@ -0,0 +1,16 @@
package cats
import simulacrum._
/**
* Weaker version of Applicative[F]; has apply but not pure.
*
* Laws:
* - apply(apply(fa)(fab))(fbc) = apply(fa)(apply(fab)(map(fbc)(bc => ab => ab andThen bc)))
*/
@typeclass trait Apply[F[_]] extends Functor[F] {
def apply[A, B](fa: F[A])(f: F[A => B]): F[B]
def map2[A, B, Z](fa: F[A], fb: F[B])(f: (A, B) => Z): F[Z] =
apply(fa)(map(fb)(b => (a: A) => f(a, b)))
}
@@ -0,0 +1,17 @@
package cats
/**
* Bijection is an invertible function.
*
* It represents both (A => B) and its inverse, (B => A).
*
* Laws:
* - inverse(apply(a)) = a
* - apply(inverse(b)) = b
* -
*/
final case class Bijection[A, B](f: A => B, g: B => A) extends Function1[A, B] {
def apply(a: A): B = f(a)
def inverse(b: B): A = g(b)
def invert: Bijection[B, A] = Bijection(g, f)
}
@@ -0,0 +1,5 @@
package cats
import simulacrum._
@typeclass trait Bimonad[F[_]] extends Monad[F] with Comonad[F]
@@ -0,0 +1,10 @@
package cats
import simulacrum._
@typeclass trait CoFlatMap[F[_]] extends Functor[F] {
def coflatMap[A, B](fa: F[A])(f: F[A] => B): F[B]
def coflatten[A](fa: F[A]): F[F[A]] =
coflatMap(fa)(fa => fa)
}
@@ -0,0 +1,7 @@
package cats
import simulacrum._
@typeclass trait Comonad[F[_]] extends CoFlatMap[F] {
def extract[A](x: F[A]): A
}
@@ -0,0 +1,13 @@
package cats
import simulacrum._
@typeclass trait FlatMap[F[_]] extends Apply[F] {
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
def flatten[A](ffa: F[F[A]]): F[A] =
flatMap(ffa)(fa => fa)
override def apply[A, B](fa: F[A])(ff: F[A => B]): F[B] =
flatMap(ff)(f => map(fa)(f))
}
@@ -0,0 +1,30 @@
package cats
import algebra.Monoid
import cats.arrow.MonoidK
import simulacrum._
@typeclass trait Foldable[F[_]] extends Functor[F] {
def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) => B): B
def foldRight[A, B](fa: F[A], b: B)(f: (A, B) => B): B
def foldMap[A, B: Monoid](fa: F[A])(f: A => B): B =
foldLeft(fa, Monoid[B].empty) { (b, a) =>
Monoid[B].combine(b, f(a))
}
def fold[A: Monoid](fa: F[A]): A =
foldMap(fa)(x => x)
def traverse_[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[Unit] =
foldLeft(fa, Applicative[G].pure(())) { (acc, a) =>
Applicative[G].map2(acc, f(a)) { (_, _) => () }
}
def sequence_[G[_]: Applicative, A, B](fga: F[G[A]]): G[Unit] =
traverse_(fga)(identity)
def psum[G[_]: MonoidK, A](fga: F[G[A]]): G[A] =
foldLeft(fga, MonoidK[G].empty[A])(MonoidK[G].combine)
}
@@ -0,0 +1,16 @@
package cats
import simulacrum._
/**
* Functor.
*
* Must obey the following laws:
* - map(fa)(identity) = fa
* - map(map(fa)(f1))(f2) = map(fa)(f2 compose f1)
*/
@typeclass trait Functor[F[_]] extends functor.Invariant[F] {
def map[A, B](fa: F[A])(f: A => B): F[B]
def fmap[A, B](f: A => B): F[A] => F[B] = fa => map(fa)(f)
def imap[A, B](fa: F[A])(f: A <=> B): F[B] = map(fa)(f)
}
@@ -0,0 +1,11 @@
package cats
object Id {
implicit val id: Bimonad[Id] =
new Bimonad[Id] {
def pure[A](a: A): A = a
def extract[A](a: A): A = a
def flatMap[A, B](a: A)(f: A => B): B = f(a)
def coflatMap[A, B](a: A)(f: A => B): B = f(a)
}
}
@@ -0,0 +1,5 @@
package cats
import simulacrum._
@typeclass trait Monad[F[_]] extends FlatMap[F] with Applicative[F]
@@ -0,0 +1,22 @@
package cats
import Id.id
import simulacrum._
@typeclass trait Traverse[F[_]] extends Functor[F] with Foldable[F] { self =>
def traverse[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]]
def sequence[G[_]: Applicative, A](fga: F[G[A]]): G[F[A]] =
traverse(fga)(ga => ga)
override def map[A, B](fa: F[A])(f: A => B): F[B] =
traverse[Id, A, B](fa)(f)
def traversal[G[_]: Applicative]: Traversal[G] =
new Traversal[G]
class Traversal[G[_]: Applicative] {
def run[A, B](fa: F[A])(f: A => G[B]): G[F[B]] = traverse[G, A, B](fa)(f)
}
}
@@ -0,0 +1,24 @@
package cats
package arrow
import cats.functor.Strong
trait Arrow[F[_, _]] extends Split[F] with Strong[F] with Category[F] { self =>
def lift[A, B](f: A => B): F[A, B]
def lmap[A, B, C](fab: F[A, B])(f: C => A): F[C, B] =
andThen(lift(f), fab)
def rmap[A, B, C](fab: F[A, B])(f: B => C): F[A, C] =
compose(lift(f), fab)
def second[A, B, C](fa: F[A, B]): F[(C, A), (C, B)] = {
def swap[X, Y] = lift[(X, Y), (Y, X)] { case (x, y) => (y, x) }
compose(swap, (compose(first[A, B, C](fa), swap)))
}
}
object Arrow {
def apply[F[_, _]](implicit ev: Arrow[F]): Arrow[F] = ev
}
@@ -0,0 +1,25 @@
package cats
package arrow
import algebra.Monoid
trait Category[F[_, _]] extends Compose[F] { self =>
def id[A]: F[A, A]
override def algebraK: MonoidK[λ[α => F[α, α]]] =
new MonoidK[λ[α => F[α, α]]] {
def empty[A] = id
def combine[A](f1: F[A, A], f2: F[A, A]) = self.compose(f1, f2)
}
override def algebra[A]: Monoid[F[A, A]] =
new Monoid[F[A, A]] {
def empty: F[A, A] = id
def combine(f1: F[A, A], f2: F[A, A]) = self.compose(f1, f2)
}
}
object Category {
def apply[F[_, _]](implicit ev: Category[F]): Category[F] = ev
}
@@ -0,0 +1,25 @@
package cats
package arrow
final case class Cokleisli[F[_], A, B](run: F[A] => B) { self =>
def apply(fa: F[A]): B = run(fa)
def dimap[C, D](f: C => A, g: B => D)(implicit b: Functor[F]): Cokleisli[F, C, D] =
Cokleisli(fc => g(run(b.map(fc)(f))))
def contramapValue[C](f: F[C] => F[A]): Cokleisli[F, C, B] =
Cokleisli(run compose f)
def map[C](f: B => C): Cokleisli[F, A, C] =
Cokleisli(f compose run)
def flatMap[C](f: B => Cokleisli[F, A, C]): Cokleisli[F, A, C] =
Cokleisli(fa => f(self.run(fa)).run(fa))
def compose[C](c: Cokleisli[F, B, C])(implicit F: CoFlatMap[F]): Cokleisli[F, A, C] =
Cokleisli(fa => c.run(F.coflatMap(fa)(run)))
def andThen[C](c: Cokleisli[F, C, A])(implicit F: CoFlatMap[F]): Cokleisli[F, C, B] =
c compose this
}
@@ -0,0 +1,25 @@
package cats
package arrow
import algebra.Semigroup
trait Compose[F[_, _]] { self =>
def compose[A, B, C](f: F[B, C], g: F[A, B]): F[A, C]
def andThen[A, B, C](f: F[A, B], g: F[B, C]): F[A, C] =
compose(g, f)
def algebraK: SemigroupK[λ[α => F[α, α]]] =
new SemigroupK[λ[α => F[α, α]]] {
def combine[A](f1: F[A, A], f2: F[A, A]) = self.compose(f1, f2)
}
def algebra[A]: Semigroup[F[A, A]] =
new Semigroup[F[A, A]] {
def combine(f1: F[A, A], f2: F[A, A]) = self.compose(f1, f2)
}
}
object Compose {
def apply[F[_, _]](implicit ev: Compose[F]): Compose[F] = ev
}
Oops, something went wrong.

0 comments on commit 9d1837e

Please sign in to comment.