scala - Shapeless HList type checking -
i using shapeless , have following method compute difference between 2 hlists:
def diff[h <: hlist](lst1: h, lst2:h):list[string] = (lst1, lst2) match { case (hnil, hnil) => list() case (h1::t1, h2::t2) if h1 != h2 => s"$h1 -> $h2" :: diff(t1, t2) case (h1::t1, h2::t2) => diff(t1, t2) case _ => throw new runtimeexception("something went wrong") }
since both parameters method take h
, expect hlists of different types not compile here. example:
diff("a" :: hnil, 1 :: 2 :: hnil)
shouldn't compile does, , produces runtime error: java.lang.runtimeexception: went wrong
. there can type parameters make method accept 2 sides identical types?
unfortunately, base hlist
trait unparameterized, , in method call h
resolved hlist
(which indeed supertype of hlist
irrespective of concrete element types). fix have change definition somewhat, , rely instead on generalized type constraints:
def diff[h1 <: hlist, h2 <: hlist](lst1: h1, lst2: h2)(implicit e: h1 =:= h2): list[string] = (lst1, lst2) match { case (hnil, hnil) => list() case (h1::t1, h2::t2) if h1 != h2 => s"$h1 -> $h2" :: diff(t1, t2) case (h1::t1, h2::t2) => diff(t1, t2) case _ => throw new runtimeexception("something went wrong") }
let's check:
scala> diff("a" :: hnil, 1 :: 2 :: hnil) <console>:12: error: cannot prove shapeless.::[string,shapeless.hnil] =:= shapeless.::[int,shapeless.::[int,shapele diff("a" :: hnil, 1 :: 2 :: hnil) ^ scala> diff("a" :: hnil, "b" :: hnil) res5: list[string] = list(a -> b) scala> diff("a" :: 1 :: hnil, "b" :: 2 :: hnil) res6: list[string] = list(a -> b, 1 -> 2)
now still "cheat" , explicitly set h1 , h2 hlist
, , we're square one.
scala> diff[hlist, hlist]("a" :: hnil, 1 :: 2 :: hnil) java.lang.runtimeexception: went wrong @ .diff(<console>:15) @ .diff(<console>:13)
unfortunately don't think solvable (it though, don't have quick solution).
Comments
Post a Comment