Skip to content

Instantly share code, notes, and snippets.

@mpilquist
Last active August 29, 2015 14:09
Show Gist options
  • Save mpilquist/6d940a84424732f78d76 to your computer and use it in GitHub Desktop.
Save mpilquist/6d940a84424732f78d76 to your computer and use it in GitHub Desktop.
Aligning coproduct types
package scodec
import shapeless._
import shapeless.ops.coproduct._
object CoproductOps {
sealed trait Align[A <: Coproduct, B <: Coproduct] {
def apply(a: A): B
}
object Align {
implicit def cnilAlign: Align[CNil, CNil] = new Align[CNil, CNil] {
def apply(cn: CNil) = cn
}
implicit def coproductAlign[A <: Coproduct, BH, BT <: Coproduct, R <: Coproduct](implicit
remove: Remove.Aux[A, BH, R], alignTail: Align[R, BT]
): Align[A, BH :+: BT] = new Align[A, BH :+: BT] {
def apply(a: A) = remove(a) match {
case Left(bh) => Inl(bh)
case Right(rest) => Inr(alignTail(rest))
}
}
}
implicit class AlignSyntax[C <: Coproduct](val self: C) extends AnyVal {
def align[To <: Coproduct](implicit align: Align[C, To]): To = align(self)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment