Skip to content

Instantly share code, notes, and snippets.

@larsrh
Last active December 16, 2015 18:30
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save larsrh/5478539 to your computer and use it in GitHub Desktop.
Sequence `HList`s
import shapeless._
import scalaz._
import scalaz.syntax.apply._
sealed trait UnapplyFirst[F[_], L <: HList] {
def TC: Applicative[F]
}
object UnapplyFirst {
implicit def unapplyFirst[H, T <: HList](implicit ev: Unapply[Applicative, H]): UnapplyFirst[ev.M, H :: T] = new UnapplyFirst[ev.M, H :: T] {
def TC = ev.TC
}
}
sealed trait Sequencer[F[_], I <: HList, O <: HList] {
def apply(in: I)(implicit F: Applicative[F]): F[O]
}
object Sequencer {
implicit def nilSequencer[F[_]]: Sequencer[F, HNil, HNil] = new Sequencer[F, HNil, HNil] {
def apply(in: HNil)(implicit F: Applicative[F]) =
F.pure(HNil: HNil)
}
implicit def consSequencer[F[_], H, T <: HList, O <: HList](implicit seq: Sequencer[F, T, O]): Sequencer[F, F[H] :: T, H :: O] = new Sequencer[F, F[H] :: T, H :: O] {
def apply(in: F[H] :: T)(implicit F: Applicative[F]) = in match {
case head :: tail =>
(head |@| seq(tail)) { _ :: _ }
}
}
}
def sequence[F[_], I <: HList, O <: HList](in: I)(implicit unapplied: UnapplyFirst[F, I], sequencer: Sequencer[F, I, O]): F[O] =
sequencer(in)(unapplied.TC)
import scalaz._
import scalaz.std.option._
import shapeless._
import shapeless.contrib.scalaz._
// works nicely
val in = Option(1) :: HNil
sequence(in)
import scalaz._
import scalaz.std.string._
import scalaz.syntax.validation._
import shapeless._
import shapeless.contrib.scalaz._
// doesn't work
val in = 3.success[String] :: HNil
sequence(in)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment