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

io.chrisdavenport.mules.Cache.scala Maven / Gradle / Ivy

The newest version!
package io.chrisdavenport.mules

import cats._
import cats.syntax.all._

trait Lookup[F[_], K, V]{
  def lookup(k: K): F[Option[V]]
}

object Lookup {

  def mapValues[F[_]: Functor, K, A, B](l: Lookup[F, K, A])(f: A => B): Lookup[F, K, B] = 
    new Lookup[F, K, B]{
      def lookup(k: K): F[Option[B]] = l.lookup(k).map(_.map(f))
    }

  def contramapKeys[F[_], K, B, A](l: Lookup[F, K, A])(f: B => K): Lookup[F, B, A] = 
    new Lookup[F, B, A]{
      def lookup(k: B): F[Option[A]] = l.lookup(f(k))
    }

  def evalMap[F[_]: Monad, K, A, B](l: Lookup[F, K, A])(f: A => F[B]): Lookup[F, K, B] = 
    new Lookup[F, K, B]{
      def lookup(k: K): F[Option[B]] = l.lookup(k).flatMap(_.traverse(f))
    }

  def mapK[F[_], G[_], K, V](l: Lookup[F, K, V])(fk: F ~> G): Lookup[G, K, V] =
    new Lookup[G, K, V]{
      def lookup(k: K): G[Option[V]] = fk(l.lookup(k))
    }
}

trait Get[F[_], K, V]{
  def get(k: K): F[V]
}

object Get {

  def mapValues[F[_]: Functor, K, A, B](l: Get[F, K, A])(f: A => B): Get[F, K, B] = 
    new Get[F, K, B]{
      def get(k: K): F[B] = l.get(k).map(f)
    }

  def contramapKeys[F[_], K, B, A](l: Get[F, K, A])(g: B => K): Get[F, B, A] = 
    new Get[F, B, A]{
      def get(k: B): F[A] = l.get(g(k))
    }

  def evalMap[F[_]: Monad, K, A, B](l: Get[F, K, A])(f: A => F[B]): Get[F, K, B] = 
    new Get[F, K, B]{
      def get(k: K): F[B] = l.get(k).flatMap(f)
    }

  def mapK[F[_], G[_], K, V](g: Get[F, K, V])(fk: F ~> G): Get[G, K, V] = 
    new Get[G, K, V]{
      def get(k: K): G[V] = fk(g.get(k))
    }

}

trait Insert[F[_], K, V]{
  def insert(k: K, v: V): F[Unit]
}

object Insert {

  def contramapValues[F[_], K, A, B](i: Insert[F, K, A])(g: B => A): Insert[F, K, B] =
    new Insert[F, K, B]{
      def insert(k: K, v: B): F[Unit] = i.insert(k, g(v))
    }

  def contramapKeys[F[_], A, B, V](i: Insert[F, A, V])(g: B => A): Insert[F, B, V] = 
    new Insert[F, B, V]{
      def insert(k: B, v: V): F[Unit] = i.insert(g(k), v)
    }

  def mapK[F[_], G[_], K, V](i: Insert[F, K, V])(fk: F ~> G): Insert[G, K, V] =
    new Insert[G, K, V]{
      def insert(k: K, v: V): G[Unit] = fk(i.insert(k, v))
    }

}

trait Delete[F[_], K]{
  def delete(k: K): F[Unit]
}

object Delete {
  def contramap[F[_], A, B](d: Delete[F, A])(g: B => A): Delete[F, B] =
    new Delete[F, B]{
      def delete(k: B) = d.delete(g(k))
    }

  def mapK[F[_], G[_], K](d: Delete[F, K])(fk: F ~> G): Delete[G, K] = 
    new Delete[G, K]{
      def delete(k: K): G[Unit] = fk(d.delete(k))
    }
}

trait Cache[F[_], K, V] 
  extends Lookup[F, K, V]
  with Insert[F, K, V]
  with Delete[F, K]

object Cache {
  def imapValues[F[_]: Functor, K, A, B](cache: Cache[F, K, A])(f: A => B, g: B => A): Cache[F, K, B] = 
    new Cache[F, K, B]{
      def lookup(k: K): F[Option[B]] = cache.lookup(k).map(_.map(f))
      def insert(k: K, v: B): F[Unit] = cache.insert(k, g(v))
      def delete(k: K): F[Unit] = cache.delete(k)
    }

  def contramapKeys[F[_], K1, K2, V](c: Cache[F, K1, V])(g: K2 => K1): Cache[F, K2, V] =
    new Cache[F, K2, V] {
      def lookup(k: K2): F[Option[V]] = c.lookup(g(k))
      def insert(k: K2, v: V): F[Unit] = c.insert(g(k), v)
      def delete(k: K2): F[Unit] = c.delete(g(k))
    }

  def evalIMap[F[_]: Monad, K, V1, V2](
    c: Cache[F, K, V1]
  )(f: V1 => F[V2], g: V2 => V1): Cache[F, K, V2] =
    new Cache[F, K, V2] {
      def lookup(k: K): F[Option[V2]] = c.lookup(k).flatMap(_.traverse(f))
      def insert(k: K, v: V2): F[Unit] = c.insert(k, g(v))
      def delete(k: K): F[Unit] = c.delete(k)
    }

  def mapK[F[_], G[_], K, V](cache: Cache[F, K, V])(fk: F ~> G): Cache[G, K, V] =
    new Cache[G, K, V]{
      def lookup(k: K): G[Option[V]] = fk(cache.lookup(k))
      def insert(k: K, v: V): G[Unit] = fk(cache.insert(k, v))
      def delete(k: K): G[Unit] = fk(cache.delete(k))
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy