Skip to content

Instantly share code, notes, and snippets.

@puffnfresh
Created March 5, 2014 21:51
Show Gist options
  • Save puffnfresh/9377378 to your computer and use it in GitHub Desktop.
Save puffnfresh/9377378 to your computer and use it in GitHub Desktop.
Another form of unboxed tagged types.
import language.higherKinds
object Tagged {
type @@[A, B] = { type T = A }
type Id[A] = A
implicit class Taggable[A](a: A) {
def tagged[B]: A @@ B = a.asInstanceOf[A @@ B]
}
implicit class Untaggable[A, B](a: A @@ B) {
def &(f: A @@ B => A @@ B): A @@ B = f(a)
def untagged: A = a.asInstanceOf[A]
}
trait ~>[F[_], G[_]] {
def apply[A](fa: F[A]): G[A]
}
trait IsoFunctor[T, F[_], G[_]] { self =>
def to: F ~> G
def from: G ~> F
def %~[A](f: G[A] => G[A]): F[A] => F[A] = a => from(f(to(a)))
def flipped = new IsoFunctor[T, G, F] {
val to = self.from
val from = self.to
}
}
object TaggedIso {
def apply[T] = new IsoFunctor[T, ({type l[A]=A @@ T})#l, Id] {
val to = new (({type l[A]=A @@ T})#l ~> Id) {
def apply[A](fa: A @@ T): Id[A] = fa.untagged
}
val from = new (Id ~> ({type l[A]=A @@ T})#l) {
def apply[A](fa: Id[A]): A @@ T = fa.tagged
}
}
}
}
object Example {
import Tagged._
trait Age
val brianAge = 10.tagged[Age] & TaggedIso[Age] %~ (_ + 13)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment