Implicit resolution fails for newtypes with shapeless `Lazy`
Nobody has claimed this yet.
- Dominant language
- Scala
- Stars
- 5.5k
- Forks
- 1.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 5
Description
Several types in cats such as NonEmptyChain are defined using the newts / newtypes approach: the advantage of this is that there is zero (runtime) overhead to using these types versus the possibly-empty equivalents; however, it leads to several issues, raised here and elsewhere:
- https://github.com/typelevel/cats/issues/3117
- https://github.com/typelevel/cats/issues/2928
- https://github.com/typelevel/cats/issues/2582
To this list I would like to add an issue with implicit resolution when using shapeless Lazy: see https://github.com/milessabin/shapeless/issues/942 for the gory details but, in short, it's impossible to write something like:
def foo(implicit tc: Lazy[Semigroup[NonEmptyChain]]): ...
The non-Lazy version works just fine (as do by-name implicits in scala 2.13+). Interestingly, the Lazy version does work if either (or both) of the following are true:
- the implementation class (
NonEmptyChainImplin this case) is public - the required implicits are explicitly re-imported at the call site (
import NonEmptyChain._)
Clearly the end-user can't control the first, and the second is far from ideal (and took several days to discover as a workaround).
It seems like a lot of these issues boil down to variations on https://github.com/scala/bug/issues/6794 and, given that this is unlikely to be fixed in its entirety any time soon, is there some benefit to considering moving away from newtype altogether?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the Lazy[Semigroup[NonEmptyChain]] case described in the issue and compare it with the non-Lazy form, using NonEmptyChain and NonEmptyChainImpl as the entry points. Review the linked shapeless and Scala issues before deciding whether a code change is possible; done requires an agreed resolution to the newtype and implicit-resolution design problem.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100