Skip to content

Instantly share code, notes, and snippets.

@arosien
Created April 2, 2015 19:24
Show Gist options
  • Save arosien/96be977a25d30c4e6a03 to your computer and use it in GitHub Desktop.
Save arosien/96be977a25d30c4e6a03 to your computer and use it in GitHub Desktop.
WIP Bloom collections via Spire Lattices
package net.rosien.lattice
import scalaz._
import scalaz.syntax.order._
/* http://db.cs.berkeley.edu/papers/UCB-lattice-tr.pdf */
sealed trait LValue[A] {
def value: A
}
trait Bloom[A] extends BoundedJoinSemilattice[LValue[A]] {
implicit def L: BoundedJoinSemilattice[A]
def point(a: A): LValue[A]
def zero: LValue[A] = point(L.zero)
def join(lhs: LValue[A], rhs: LValue[A]): LValue[A] = point(L.join(lhs.value, rhs.value))
}
object Bloom {
type LBool = LValue[Boolean]
type LMax[A] = LValue[MaxOf[A]]
type LMin[A] = LValue[MinOf[A]]
type LSet[A] = LValue[Set[A]]
def apply[A](implicit B: Bloom[A]): Bloom[A] = B
implicit object BooleanBJS extends BoundedJoinSemilattice[Boolean] {
def join(lhs: Boolean, rhs: Boolean): Boolean = lhs || rhs
val zero: Boolean = false
}
implicit def MaxBJS[A : Enum]: BoundedJoinSemilattice[MaxOf[A]] =
new BoundedJoinSemilattice[MaxOf[A]] {
def join(lhs: MaxOf[A], rhs: MaxOf[A]): MaxOf[A] =
Tags.MaxVal(Tags.MaxVal.unwrap(lhs) max Tags.MaxVal.unwrap(rhs))
def zero: MaxOf[A] = Tags.MaxVal(Enum[A].min.get) // YOLO
}
implicit def MinBJS[A : Enum]: BoundedJoinSemilattice[MinOf[A]] =
new BoundedJoinSemilattice[MinOf[A]] {
def join(lhs: MinOf[A], rhs: MinOf[A]): MinOf[A] =
Tags.MinVal(Tags.MinVal.unwrap(lhs) min Tags.MinVal.unwrap(rhs))
def zero: MinOf[A] = Tags.MinVal(Enum[A].max.get) // YOLO
}
implicit def SetBJS[A]: BoundedJoinSemilattice[Set[A]] =
new BoundedJoinSemilattice[Set[A]] {
def join(lhs: Set[A],rhs: Set[A]): Set[A] = lhs union rhs
def zero: Set[A] = Set.empty
}
private case class Impl[A](value: A) extends LValue[A]
implicit object LBool extends Bloom[Boolean] {
implicit def L = BooleanBJS
def point(a: Boolean): LBool = Impl(a)
}
implicit def LMax[A : Enum]: Bloom[MaxOf[A]] =
new Bloom[MaxOf[A]] {
implicit def L = MaxBJS[A]
def point(a: MaxOf[A]): LMax[A] = Impl(a)
}
def lvalue[F[_], A, B](fa: F[A])(f: A => B)(implicit FF: Foldable[F], BB: Bloom[B]): LValue[B] =
BB.point(FF.foldLeft(fa, BB.L.zero)((b, a) => BB.L.join(b, f(a))))
def whenTrue(lbool: LBool): Option[Boolean] =
if (lbool.value) Some(lbool.value)
else None
def gt[A : Order](lmax: LMax[A])(o: A): LBool =
LBool.point(Tags.MaxVal.unwrap(lmax.value) gt o)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment