Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save danclien/3bfce6628e06973d5075 to your computer and use it in GitHub Desktop.
Save danclien/3bfce6628e06973d5075 to your computer and use it in GitHub Desktop.
import scalaz._, Scalaz._, shapeless._, ops.hlist.{ RightFolder, Tupler }
// Might as well stay generic in `F` for this part.
object applicativeFolder extends Poly2 {
implicit def caseApplicative[A, B <: HList, F[_]](implicit
app: Applicative[F]
) = at[F[A], F[B]] {
(a, b) => app.ap(a)(app.map(b)(bb => (_: A) :: bb))
}
}
// It should be possible to make this part generic in `F` as well,
// but type inference makes it tricky, so we specialize to `Option`.
def sequence[T, EL <: HList, L <: HList, OL <: HList, OT](t: T)(implicit
gen: Generic.Aux[T, EL],
eq: EL =:= L,
folder: RightFolder.Aux[L, Option[HNil], applicativeFolder.type, Option[OL]],
tupler: Tupler.Aux[OL, OT]
): Option[OT] =
eq(gen.to(t)).foldRight(some(HNil: HNil))(applicativeFolder).map(tupler(_))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment