Skip to content

Instantly share code, notes, and snippets.

@andyscott
Last active May 10, 2018 21:50
Show Gist options
  • Save andyscott/3791545d4874f8199725c673f123c7b8 to your computer and use it in GitHub Desktop.
Save andyscott/3791545d4874f8199725c673f123c7b8 to your computer and use it in GitHub Desktop.
Generic unzip Lists[TupleN] with Shapeless
import shapeless._
object emptyList extends Poly0 {
implicit def default[T] = at[List[T]](List.empty)
}
object appendList extends Poly2 {
implicit def default[T] = at[T, List[T]](_ :: _)
}
def unzip[P, L <: HList, LL <: HList, T](list: List[P])(
implicit
gen : Generic.Aux[P, L],
mapped: ops.hlist.Mapped.Aux[L, List, LL],
append: ops.hlist.ZipWith.Aux[L, LL, appendList.type, LL],
empty : ops.hlist.FillWith[emptyList.type, LL],
tup : ops.hlist.Tupler.Aux[LL, T]
): T =
tup(list.foldRight(empty())((v, acc) => append(gen.to(v), acc)))
val input: List[(String, Int, String)] = List(("hello", 1, "world"), ("foo", 2, "bar"))
val (z0, z1, z2) = unzip(input)
println(z0) // List(hello, world)
println(z1) // List(1, 2)
println(z2) // List(world, bar)
@ShaneDelmore
Copy link

That is pretty handy 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment