Skip to content

Instantly share code, notes, and snippets.

@tel
Created November 2, 2016 21:59
Show Gist options
  • Save tel/5ac334d8618841bb55ca915dded09437 to your computer and use it in GitHub Desktop.
Save tel/5ac334d8618841bb55ca915dded09437 to your computer and use it in GitHub Desktop.
Quantities and quantified sets
package jspha.comms
import scala.language.higherKinds
sealed trait Quantity {
type T[_]
}
object Singular extends Quantity { self =>
case class T[A](v: A) extends Quantity.Set[A] {
type T = self.type
}
}
object Optional extends Quantity { self =>
case class T[A](v: Option[A]) extends Quantity.Set[A] {
type T = self.type
}
}
object Multiple extends Quantity { self =>
case class T[A](v: List[A]) extends Quantity.Set[A] {
type T = self.type
}
}
object Quantity {
type Singular = Singular.type
type Optional = Optional.type
type Multiple = Multiple.type
/**
* A "quantified set" of values A consists of either one value A, the option
* of having a value A, or many values of A. In this sense, it's easy to
* subsume a quantified set into a simple list, but quantified sets have a
* special relationship with Cardinalities.
*/
sealed trait Set[A] {
type T <: Quantity
}
trait Narrowing[Q <: Quantity] {
def pf[A]: PartialFunction[Set[A], Q#T[A]]
def apply[A](set: Set[A]): Option[Q#T[A]] = pf.lift(set)
}
object Narrowing {
implicit val SingularNarrowing: Narrowing[Singular] =
new Narrowing[Singular] {
def pf[A] = { case Singular.T(v) => Singular.T(v) }
}
implicit val OptionalNarrowing: Narrowing[Optional] =
new Narrowing[Optional] {
def pf[A] = { case Optional.T(v) => Optional.T(v) }
}
implicit val MultipleNarrowing: Narrowing[Multiple] =
new Narrowing[Multiple] {
def pf[A] = { case Multiple.T(v) => Multiple.T(v) }
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment