Skip to content

Instantly share code, notes, and snippets.

@andyscott
Created February 10, 2016 04:22
Show Gist options
  • Select an option

  • Save andyscott/f944c70666061845aee8 to your computer and use it in GitHub Desktop.

Select an option

Save andyscott/f944c70666061845aee8 to your computer and use it in GitHub Desktop.
package fail.sauce.example123
import cats.Monad
import shapeless.{HList, HNil, ::}
import shapeless.Poly2
import shapeless.UnaryTCConstraint
import shapeless.UnaryTCConstraint.*->*
import shapeless.ops.hlist.RightFolder
object Example extends App {
println("example time")
object monadFolder extends Poly2 {
implicit def caseApplicative[A, B <: HList, F[_]: Monad] = at[F[A], F[B]] {
(a, b) => Monad[F].ap(Monad[F].map(b)(bb => (_: A) :: bb))(a)
}
}
def hlistMagic1[F[_]: Monad, L <: HList: *->*[F]#λ, M <: HList](l: L)(
implicit
folder: RightFolder.Aux[L, F[HNil], monadFolder.type, F[M]]
): F[M] = l.foldRight(Monad[F].pure(HNil: HNil))(monadFolder)
// using context bounds and kind projector plugin (instead of type lambdas)
def hlistMagic2[
F[_]: Monad,
L <: HList : UnaryTCConstraint[?, F] : RightFolder.Aux[?, F[HNil], monadFolder.type, F[M]],
M <: HList
] (l: L): F[M] =
l.foldRight(Monad[F].pure(HNil: HNil))(monadFolder)
import cats.std.option._
val input = Option("hello") :: Option(1) :: Option("world") :: HNil
val output1: Option[String :: Int :: String :: HNil] = hlistMagic1(input)
val output2: Option[String :: Int :: String :: HNil] = hlistMagic2(input)
println("output1 " + output1)
println("output2 " + output2)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment