Find type class instances for Shapeless HList
Asked Answered
A

1

8

Say that I have a trait Show[T] such as the one in Scalaz: https://github.com/scalaz/scalaz/blob/scalaz-seven/core/src/main/scala/scalaz/Show.scala#L9

I also have a Shapeless HList that may look like "1" :: 2 :: 3L :: HNil.

Is there a way to find the Show instance for each element and apply shows such that I end up with "1" :: "2" :: "3L" :: HNil?

If any element were of a type that did not have an implicit Show instance in scope I would want a compile error.

I think that if I build up an HList of the Show instances I should be able to use zipApply to get the HList I want, but I don't know if there is a way to get have Scala infer the HList of Show instances instead of me building it up by hand.

Amandy answered 8/3, 2014 at 12:28 Comment(0)
M
9

If your goal is to apply the Show instances and you don't otherwise care about building up an HList of them, the easiest approach is probably to use a polymorphic function:

import scalaz._, Scalaz._, shapeless._

val xs = "1" :: 2 :: 3L :: HNil

object show extends Poly1 {
  implicit def forShowable[A: Show] = at[A](_.shows)
}

val strings: String :: String :: String :: HNil = xs map show

You could get an HList of the instances by changing the Poly1 a bit:

object showInstance extends Poly1 {
  implicit def forShowable[A: Show] = at[A](_ => Show[A])
}

In some cases it can be useful to define your own type class to collect evidence that you've got certain type class instances:

trait AllShowable[L <: HList, S <: HList] {
  def instances: S
}

implicit object hnilAllShowable extends AllShowable[HNil, HNil] {
  def instances = HNil
}

implicit def hlistAllShowable[H: Show, TL <: HList, TS <: HList](
  implicit ts: AllShowable[TL, TS]
) = new AllShowable[H :: TL, Show[H] :: TS] {
  def instances = Show[H] :: ts.instances
}

But usually mapping with a polymorphic function that requires the instances will work just fine.

Maurene answered 8/3, 2014 at 13:8 Comment(2)
How do you answer these so fast, Travis? When I posted this I had a feeling that the answer would either be "this is impossible" or the solution would be so simple that I would end up feeling dumb. Pleased to see that it's the latter :)Amandy
I'm working on an endless project on a Saturday morning, so being able to answer questions like this is a very welcome morale boost. And I'm not sure any well-formulated question about Shapeless could be considered "dumb".Maurene

© 2022 - 2024 — McMap. All rights reserved.