Skip to content

Instantly share code, notes, and snippets.

@psttf
Created November 25, 2013 11:50
Show Gist options
  • Save psttf/7640184 to your computer and use it in GitHub Desktop.
Save psttf/7640184 to your computer and use it in GitHub Desktop.
ConstZipper zips an HList with a constant value
import shapeless._
object cz {
trait ConstZipper[L <: HList, C] extends DepFn2[L, C] { type Out <: HList }
object ConstZipper {
type Aux[L <: HList, C, Out0 <: HList] =
ConstZipper[L, C] { type Out = Out0 }
implicit def hnilConstZipper[C]: Aux[HNil, C, HNil] =
new ConstZipper[HNil, C] {
type Out = HNil
def apply(l : HNil, c : C): Out = l
}
implicit def hlistConstZipper[H, T <: HList, C](implicit
mct : ConstZipper[T, C]
) = new ConstZipper[H :: T, C] {
type Out = (H, C) :: mct.Out
def apply(l : H :: T, c : C): Out = (l.head,c) :: mct(l.tail, c)
}
}
def constZip[L <: HList, C, Out0 <: HList](l: L, c: C)(implicit
icz : ConstZipper.Aux[L, C, Out0]
): Out0 = icz(l, c)
}
import cz._
val l = 1 :: "a" :: true :: HNil
constZip(l, "const")
@travisbrown
Copy link

You can gather the implicit evidence for a zip and mapConst like this:

def constZip[L <: HList, A, CM <: HList](l: L, a: A)(implicit
  cm: ops.hlist.ConstMapper.Aux[A, L, CM],
  z: ops.hlist.Zip[L :: CM :: HNil]
) = l zip (l mapConst a)

For the record, def constZip[L <: HList, A](l: L, a: A) = l zip (l mapConst a) only compiled because of this bug, which was fixed last month.

@psttf
Copy link
Author

psttf commented Nov 26, 2013

Thank you! That really looks easier to understand. And also explains the purpose of Aux classes.

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