Skip to content

Instantly share code, notes, and snippets.

@joroKr21
Created October 28, 2016 08:53
Show Gist options
  • Save joroKr21/605fa605bed9953cc2bfc63c7c099564 to your computer and use it in GitHub Desktop.
Save joroKr21/605fa605bed9953cc2bfc63c7c099564 to your computer and use it in GitHub Desktop.
import shapeless._
import shapeless.ops.coproduct.Selector
import shapeless.ops.coproduct.ToHList
import shapeless.ops.hlist.LiftAll
import shapeless.ops.hlist.Mapper
import shapeless.ops.hlist.ZipConst
object Partition extends App {
trait Dummy[-A]
object Dummy {
implicit val instance: Dummy[Any] =
new Dummy[Any] { }
}
object partitioner extends Poly1 {
implicit def caseSel[Sum <: Coproduct, A](implicit sel: Selector[Sum, A]) =
at[(Dummy[A], List[Sum])](_._2.flatMap(sel.apply))
}
def partition[
Sum <: Coproduct,
Product <: HList,
Dummies <: HList,
Zipped <: HList
](sums: List[Sum])(
implicit
SumToProduct: ToHList.Aux[Sum, Product],
Dummy: LiftAll.Aux[Dummy, Product, Dummies],
zipWith: ZipConst.Aux[List[Sum], Dummies, Zipped],
partition: Mapper[partitioner.type, Zipped]
) = partition(zipWith(sums, Dummy.instances))
type Sum = Int :+: String :+: BigInt :+: CNil
val sums: List[Sum] = List(
Coproduct[Sum](1),
Coproduct[Sum](2),
Coproduct[Sum](3),
Coproduct[Sum](4),
Coproduct[Sum](5),
Coproduct[Sum]("str1"),
Coproduct[Sum]("str2"),
Coproduct[Sum]("str3"),
Coproduct[Sum]("str4"),
Coproduct[Sum]("str5"))
println(partition(sums))
// List(1, 2, 3, 4, 5) :: List(str1, str2, str3, str4, str5) :: List() :: HNil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment