Open milessabin opened 10 years ago
It should be possible to write a method that takes a Zipper argument and yields the result of .right.get
.
Not sure to understand what you mean by composability... Do you have the signature of the function you imagine and a short description?
@mandubian I've updated the description to make it clearer what the issue actually is. I've also removed the "Low hanging fruit" label because I think it might be quite fiddly to solve in a satisfying way.
It compiles & works with:
def getRight[T, L <: HList](t: T)
(implicit gen: Generic.Aux[T, L],
right: Right[Zipper[T, HNil, L, None.type]]
) = Zipper(t).right
But we can't write:
def getRight[T, RH, RL <: HList](t: T)
(implicit gen: Generic.Aux[T, RH :: RL],
right: Right[Zipper[T, HNil, RH :: RL, None.type]]
) = Zipper(t).right
The Generic.Aux[T, RH :: RL]
can't be inferred by the compiler (the whitebox macro mustn't help it).
If we could write this, it would be easy to infer the Zipper
from the Generic.Aux
and finally to infer the Right
from the Zipper
with something like:
implicit def hasRight[C, L <: HList, RH, RT <: HList, P](zipper: Zipper[C, L, RH::RT, P]): Right[Zipper[C, L, RH::RT, P]] = Right.right[C, L, RH, RT, P]
In this case, we wouldn't need the implicit Right[Zipper[...]]
in the def getRight
but it's not possible as is...
The problem is visible when you try and use the zipper in a polymorphic function. If you've used shapeless you'd expect the function to need a bunch of implicit zipper operation witnesses before you can perform the corresponding operation within the method body. Unfortunately it's extremely difficult to write the signatures for those witnesses. For instance in,
what should we write as the type argument for
Right
in the implicit parameter block above?