Created
March 5, 2014 21:51
-
-
Save puffnfresh/9377378 to your computer and use it in GitHub Desktop.
Another form of unboxed tagged types.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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