Skip to content

Instantly share code, notes, and snippets.

@sideeffffect
Created September 11, 2019 09:39
Show Gist options
  • Save sideeffffect/f391bacd5db9f96a8ca45b85b95ece85 to your computer and use it in GitHub Desktop.
Save sideeffffect/f391bacd5db9f96a8ca45b85b95ece85 to your computer and use it in GitHub Desktop.
object TypeClasses {
trait Monoid[A] {
def combine(x: A, y: A): A
def empty: A
}
implicit object IntPlusMonoid extends Monoid[Int] {
override def combine(x: Int, y: Int): Int = x + y
override def empty: Int = 0
}
def associativity[A](x: A, y: A, z: A)(implicit m: Monoid[A]): Boolean = {
import m._
combine(x, combine(y, z)) == combine(combine(x, y), z)
}
def identityElem[A](x: A)(implicit m: Monoid[A]): Boolean = {
import m._
combine(empty, x) == combine(x, empty) &&
combine(empty, x) == x &&
combine(x, empty) == x
}
val mx: List[Int] = List()
val fy: Int => List[Int] = _ => List()
for {
x <- mx
y <- fy(x)
} yield x + y
trait Functor[F[_]] {
def map[A, B](m: F[A])(f: A => B): F[B]
}
trait Monad[F[_]] extends Functor[F] {
def flatMap[A, B](m: F[A])(f: A => F[B]): F[B]
def pure[A](x: A): F[A]
override def map[A, B](m: F[A])(f: A => B): F[B] = flatMap(m)(x => pure(f(x)))
// for {
// x <- m
// } yield f(m)
}
object FunctorOption extends Functor[Option] {
override def map[A, B](m: Option[A])(f: A => B): Option[B] = m match {
case Some(value) => Some(f(value))
case None => None
}
}
object MonadOption extends Monad[Option] {
override def flatMap[A, B](m: Option[A])(f: A => Option[B]): Option[B] = m match {
case Some(value) => f(value)
case None => None
}
override def pure[A](x: A): Option[A] = Some(x)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment