All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sjc.delta.cats.instances.scala Maven / Gradle / Ivy

The newest version!
package sjc.delta.cats

import cats.arrow.Profunctor
import scala.language.higherKinds
import sjc.delta.Delta
import sjc.delta.Delta.Aux
import cats.{Applicative, Contravariant, Monad}

import scala.annotation.tailrec



object instances {
  implicit def deltaApplicative[In]: Applicative[Aux[In, *]] = new Applicative[Aux[In, *]] {
    override def map[A, B](deltaA: Aux[In, A])(ab: A => B):              Aux[In, B] = deltaA.map(ab)
    def ap[A, B](deltaAB: Aux[In, A => B])(deltaA: Aux[In, A]): Aux[In, B] = deltaA.applyTo(deltaAB)
    override def product[A, B](deltaA: Aux[In, A], deltaB: Aux[In, B]): Aux[In, (A, B)] = deltaA.zip(deltaB)
    def pure[A](a: A):                                         Aux[In, A] = Delta.const[In, A](a)
  }

  implicit def deltaMonad[In]: Monad[Aux[In, *]] = new Monad[Aux[In, *]] {
    def pure[A](a: A):                                                Aux[In, A] = Delta.const[In, A](a)
    def flatMap[A, B](deltaA: Aux[In, A])(aDeltaB: (A) => Aux[In, B]): Aux[In, B] = deltaA.flatMap(aDeltaB)

    def tailRecM[A, B](a: A)(f: A => Aux[In, Either[A, B]]): Aux[In, B] = Delta.from[In].curried(left => right => {
      @tailrec def recurse(current: A): B = f(a).apply(left, right) match {
        case Left(newA) => recurse(newA)
        case Right(b)   => b
      }

      recurse(a)
    })
  }

  implicit def deltaContravariant[Out]: Contravariant[Aux[*, Out]] = new Contravariant[Aux[*, Out]] {
    def contramap[A, B](delta: Aux[A, Out])(f: B => A): Aux[B, Out] = delta.contramap(f)
  }

  implicit val deltaProfunctor: Profunctor[Aux] = new Profunctor[Aux] {
    def dimap[A, B, C, D](delta: Aux[A, B])(f: C => A)(g: B => D): Aux[C, D] = delta.dimap(f, g)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy