Transitive LUB?

What needs to be changed in this fragment which it compiles?

import shapeless._ import LUBConstraint._ import ops.hlist.Prepend class Foo[L <: HList: <<:[Int]#λ](val l: L) { def ++[H <: HList: <<:[Int]#λ](h: H)(implicit prepend: Prepend[L, H]) = { new Foo(l ::: h) } } 

Currently

 could not find implicit value for evidence parameter of type shapeless.LUBConstraint[prepend.Out,Int] 
+6
source share
1 answer

Good question ... you were very close :-)

The problem is that although this is obvious to us, the Scala compiler cannot conclude that the concatenation of two HLists from Int is an HList of Int elements. We can help him by pulling the concatenation type into a type variable ( Out , pay attention to using an alias of type Prepend.Aux to restrict this new type variable), and then asking him directly to prove that Out has the required property (requiring proof of the Out form),

 import shapeless._ import ops.hlist.Prepend import LUBConstraint._ class Foo[L <: HList: <<:[Int]#λ](val l: L) { def ++[H <: HList: <<:[Int]#λ, Out <: HList](h: H) (implicit prepend: Prepend.Aux[L, H, Out], ev: LUBConstraint[Out, Int]) = { new Foo(l ::: h) } } 
+7
source

Source: https://habr.com/ru/post/974247/


All Articles