Skip to content

Instantly share code, notes, and snippets.

@DanielaSfregola
Last active August 16, 2020 03:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save DanielaSfregola/ddf48f6c5638f6284b563798c55d5ebd to your computer and use it in GitHub Desktop.
Save DanielaSfregola/ddf48f6c5638f6284b563798c55d5ebd to your computer and use it in GitHub Desktop.
tutorial-cat-solutions
package com.danielasfregola.tutorial.cat.applicative
import com.danielasfregola.tutorial.cat.functor.Functor
trait Applicative[Box[_]] extends Functor[Box] {
def pure[A](a: A): Box[A]
def ap[A, B](boxF: Box[A => B])(boxA: Box[A]): Box[B]
override def map[A, B](boxA: Box[A])(f: A => B): Box[B] =
ap[A, B](pure(f))(boxA)
}
package com.danielasfregola.tutorial.cat.applicative
import com.danielasfregola.tutorial.cat._
object ApplicativeInstances {
implicit val maybeApplicative: Applicative[Maybe] = new Applicative[Maybe] {
override def pure[A](a: A): Maybe[A] = Just(a)
override def ap[A, B](boxF: Maybe[A => B])(boxA: Maybe[A]): Maybe[B] = (boxF, boxA) match {
case (Just(f), Just(a)) => pure(f(a))
case _ => Empty
}
}
implicit val zeroOrMoreApplicative: Applicative[ZeroOrMore] = new Applicative[ZeroOrMore] {
override def pure[A](a: A): ZeroOrMore[A] = OneOrMore(a, Zero)
override def ap[A, B](boxF: ZeroOrMore[(A) => B])(boxA: ZeroOrMore[A]): ZeroOrMore[B] = (boxF, boxA) match {
case (OneOrMore(hF, _), OneOrMore(h, tail)) => OneOrMore(hF(h), ap(boxF)(tail))
case _ => Zero
}
}
}
package com.danielasfregola.tutorial.cat.functor
import com.danielasfregola.tutorial.cat._
object FunctorInstances {
implicit val maybeFunctor: Functor[Maybe] = new Functor[Maybe] {
override def map[A, B](boxA: Maybe[A])(f: (A) => B): Maybe[B] = boxA match {
case Just(a) => Just(f(a))
case Empty => Empty
}
}
implicit val zeroOrMoreFunctor: Functor[ZeroOrMore] = new Functor[ZeroOrMore] {
override def map[A, B](boxA: ZeroOrMore[A])(f: (A) => B): ZeroOrMore[B] = boxA match {
case OneOrMore(a, tail) => OneOrMore(f(a), map(tail)(f))
case Zero => Zero
}
}
}
package com.danielasfregola.tutorial.cat.monad
import com.danielasfregola.tutorial.cat.applicative.Applicative
trait Monad[Box[_]] extends Applicative[Box] {
def flatMap[A, B](boxA: Box[A])(f: A => Box[B]): Box[B]
def flatten[A](boxBoxA: Box[Box[A]]): Box[A] =
flatMap(boxBoxA)(identity)
override def ap[A, B](boxF: Box[A => B])(boxA: Box[A]): Box[B] =
flatMap(boxF)(f => map(boxA)(f))
override def map[A, B](boxA: Box[A])(f: A => B): Box[B] =
flatMap(boxA)(a => pure(f(a)))
}
package com.danielasfregola.tutorial.cat.monad
import com.danielasfregola.tutorial.cat._
import com.danielasfregola.tutorial.cat.applicative.ApplicativeInstances
object MonadInstances {
implicit val maybeMonad: Monad[Maybe] = new Monad[Maybe] {
override def flatMap[A, B](boxA: Maybe[A])(f: (A) => Maybe[B]): Maybe[B] = boxA match {
case Just(a) => f(a)
case Empty => Empty
}
override def pure[A](a: A): Maybe[A] = ApplicativeInstances.maybeApplicative.pure(a)
}
implicit val zeroOrMoreMonad: Monad[ZeroOrMore] = new Monad[ZeroOrMore] {
override def flatMap[A, B](boxA: ZeroOrMore[A])(f: (A) => ZeroOrMore[B]): ZeroOrMore[B] = boxA match {
case OneOrMore(h, tail) => f(h).append(flatMap(tail)(f))
case Zero => Zero
}
override def pure[A](a: A): ZeroOrMore[A] = ApplicativeInstances.zeroOrMoreApplicative.pure(a)
}
}
package com.danielasfregola.tutorial.cat.monoid
object MonoidInstances {
implicit val intMonoid: Monoid[Int] = new Monoid[Int] {
override def compose(x: Int, y: Int): Int = x + y
override def identity: Int = 0
}
implicit val stringMonoid: Monoid[String] = new Monoid[String] {
override def compose(x: String, y: String): String = x + y
override def identity: String = ""
}
}
@seoh
Copy link

seoh commented Oct 5, 2017

There is object MonadInstances in Monoid Instances file.

@DanielaSfregola
Copy link
Author

Thanks @seoh, I have updated the file!

@kpritam
Copy link

kpritam commented Jun 24, 2018

Shouldn't this
override def pure[A](a: A): Maybe[A] = Just(a)
be

override def pure[A](a: A): Maybe[A] = Option.apply(a) match {
      case Some(`a`) ⇒ Just(a)
      case None ⇒ Empty
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment