I am trying to use shapeless to choose the "non-empty" value from two HLists:
import shapeless.{ HNil, Poly2}
object choose extends Poly2 {
implicit def caseInt =
at[Int,Int]{
case (_,n) if n > 0 => n
case (o,_) => o
}
implicit def caseString =
at[String,String] {
case (_,n) if n.nonEmpty => n
case(o,_) => o
}
}
val g = "a" :: "" :: 0 :: HNil
val h = "" :: "a" :: 5 :: HNil
g.zip(h).map(choose)
I get an error on missing implicit mapper If I understand correctly I need to provide proof that the result of the zip is mappable but I am not sure how to do that
You are very close, but the definition of choose
is slightly wrong: map
takes a Poly1
not a Poly2
.
You're mapping over an hlist of tuples, so you need a polymorphic function taking a single argument (a tuple). What you are providing is instead a polymorphic function taking two arguments. The difference is subtle, but it's there.
Here's a version that works:
import shapeless.{ HNil, Poly1 }
object choose extends Poly1 {
implicit def caseInt =
at[(Int,Int)]{
case (_,n) if n > 0 => n
case (o,_) => o
}
implicit def caseString =
at[(String,String)] {
case (_,n) if n.nonEmpty => n
case(o,_) => o
}
}
val g = "a" :: "" :: 0 :: HNil
val h = "" :: "a" :: 5 :: HNil
g.zip(h).map(choose) // "a" :: "a" :: 5 :: HNil
As you can see what does the trick is extending Poly1
instead of Poly2
and defining the at
cases on tuples.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With