Skip to content

Instantly share code, notes, and snippets.

@OlivierBlanvillain
Last active May 25, 2017 11:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OlivierBlanvillain/103a801b0b38589c0032ee23cec9482e to your computer and use it in GitHub Desktop.
Save OlivierBlanvillain/103a801b0b38589c0032ee23cec9482e to your computer and use it in GitHub Desktop.
trait Eq[A] {
def eqv(x: A, y: A): Boolean
def neqv(x: A, y: A): Boolean
}
trait Order[A] {
def compare(x: A, y: A): Int
def min(x: A, y: A): A
def max(x: A, y: A): A
def eqv(x: A, y: A): Boolean
def neqv(x: A, y: A): Boolean
def lteqv(x: A, y: A): Boolean
def lt(x: A, y: A): Boolean
def gteqv(x: A, y: A): Boolean
def gt(x: A, y: A): Boolean
}
trait FunctionK[F[_], G[_]] {
def apply[A](fa: F[A]): G[A]
}
trait FunctorFilter[F[_]] {
def mapFilter[A, B](fa: F[A])(f: A => Option[B]): F[B]
def flattenOption[A](fa: F[Option[A]]): F[A]
}
trait Bifoldable[F[_, _]] {
def bifoldLeft[A, B, C](fab: F[A, B], c: C)(f: (C, A) => C, g: (C, B) => C): C
}
trait Foldable[F[_]] {
def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) => B): B
}
trait SemigroupK[F[_]] {
def combineK[A](x: F[A], y: F[A]): F[A]
}
trait MonoidK[F[_]] extends SemigroupK[F] {
def empty[A]: F[A]
}
trait Bifunctor[F[_, _]] {
def bimap[A, B, C, D](fab: F[A, B])(f: A => C, g: B => D): F[C, D]
}
// Groups ---------------------------------------------------------------------
trait Semigroup[A] {
def combine(x: A, y: A): A
}
trait Monoid[A] extends Semigroup[A] {
def empty: A
// def isEmpty(a: A)(implicit ev: Eq[A]): Boolean
}
trait BoundedSemilattice[A] extends Semilattice[A] with CommutativeMonoid[A]
trait CommutativeGroup[A] extends Group[A] with CommutativeMonoid[A]
trait Group[A] extends Monoid[A] {
def inverse(a: A): A
}
trait CommutativeMonoid[A] extends Monoid[A] with CommutativeSemigroup[A]
trait Semilattice[A] extends Band[A] with CommutativeSemigroup[A]
trait Band[A] extends Semigroup[A]
trait CommutativeSemigroup[A] extends Semigroup[A]
// Arrows ---------------------------------------------------------------------
trait Profunctor[F[_, _]] {
def dimap[A, B, C, D](fab: F[A, B])(f: C => A)(g: B => D): F[C, D]
def lmap[A, B, C](fab: F[A, B])(f: C => A): F[C, B]
def rmap[A, B, C](fab: F[A, B])(f: B => C): F[A, C]
}
trait Strong[F[_, _]] extends Profunctor[F] {
def first[A, B, C](fa: F[A, B]): F[(A, C), (B, C)]
def second[A, B, C](fa: F[A, B]): F[(C, A), (C, B)]
}
trait Arrow[F[_, _]] extends Split[F] with Strong[F] with Category[F] {
def lift[A, B](f: A => B): F[A, B]
def dimap[A, B, C, D](fab: F[A, B])(f: C => A)(g: B => D): F[C, D]
def second[A, B, C](fa: F[A, B]): F[(C, A), (C, B)]
def split[A, B, C, D](f: F[A, B], g: F[C, D]): F[(A, C), (B, D)]
}
trait Category[F[_, _]] extends Compose[F] {
def id[A]: F[A, A]
}
trait Choice[F[_, _]] extends Category[F] {
def choice[A, B, C](f: F[A, C], g: F[B, C]): F[Either[A, B], C]
def codiagonal[A]: F[Either[A, A], A]
}
trait Split[F[_, _]] extends Compose[F] {
def split[A, B, C, D](f: F[A, B], g: F[C, D]): F[(A, C), (B, D)]
}
trait Compose[F[_, _]] {
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]
}
// Functors -------------------------------------------------------------------
trait Contravariant[F[_]] extends Invariant[F] {
def contramap[A, B](fa: F[A])(f: B => A): F[B]
def imap[A, B](fa: F[A])(f: A => B)(fi: B => A): F[B]
}
trait Invariant[F[_]] {
def imap[A, B](fa: F[A])(f: A => B)(g: B => A): F[B]
}
trait Functor[F[_]] extends Invariant[F] {
def map[A, B](fa: F[A])(f: A => B): F[B]
def imap[A, B](fa: F[A])(f: A => B)(fi: B => A): F[B]
def lift[A, B](f: A => B): F[A] => F[B]
def void[A](fa: F[A]): F[Unit]
def fproduct[A, B](fa: F[A])(f: A => B): F[(A, B)]
def as[A, B](fa: F[A], b: B): F[B]
def tupleLeft[A, B](fa: F[A], b: B): F[(B, A)]
def tupleRight[A, B](fa: F[A], b: B): F[(A, B)]
}
trait Cartesian[F[_]] {
def product[A, B](fa: F[A], fb: F[B]): F[(A, B)]
}
trait ContravariantCartesian[F[_]] extends Cartesian[F] with Contravariant[F]
trait Apply[F[_]] extends Functor[F] with Cartesian[F] {
def ap[A, B](ff: F[A => B])(fa: F[A]): F[B]
def ap2[A, B, Z](ff: F[(A, B) => Z])(fa: F[A], fb: F[B]): F[Z]
def map2[A, B, Z](fa: F[A], fb: F[B])(f: (A, B) => Z): F[Z]
}
trait FlatMap[F[_]] extends Apply[F] {
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
def >>=[A, B](fa: F[A])(f: A => F[B]): F[B]
def flatten[A](ffa: F[F[A]]): F[A]
def followedBy[A, B](fa: F[A])(fb: F[B]): F[B]
@inline def >>[A, B](fa: F[A])(fb: F[B]): F[B]
def forEffect[A, B](fa: F[A])(fb: F[B]): F[A]
@inline def <<[A, B](fa: F[A])(fb: F[B]): F[A]
def ap[A, B](ff: F[A => B])(fa: F[A]): F[B]
def product[A, B](fa: F[A], fb: F[B]): F[(A, B)]
def mproduct[A, B](fa: F[A])(f: A => F[B]): F[(A, B)]
def ifM[B](fa: F[Boolean])(ifTrue: => F[B], ifFalse: => F[B]): F[B]
def tailRecM[A, B](a: A)(f: A => F[Either[A, B]]): F[B]
}
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]]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment