-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generic instance does not work for single-constructor-single-argument types #24
Comments
@kosmikus suggested a possible way out here; I will try and if it works, will submit a PR. |
I think possibly something has got lazier and this is now biting on single-constructor multi-field types? We are upgrading our codebase to GHC 9.6 and we got an unexpected nothunks error in a single-constructor two-field record type with
and the error went away. I don't have a small reproducer yet, sorry, but it does seem like it has something to do with the generic conversion. |
@michaelpj I doubt it's that. We have other places where What looks suspicious is that in the offending case
Not sure. |
If that was it then I don't know why changing the instance definition for |
The default definition of
wNoThunks
currently isThe problem is with the bang on the
fp
, comment notwithstanding. First, let's consider the case of a datatype with a single constructor with two fields:Evaluation would proceed something like this:
In this case the
$!
actually is not making any difference: the instance for products will pattern match on the:*:
constructor, which will force the evaluation of thecase MkT ..
anyway.The case for a datatype with multiple constructors is similar:
Now evaluation proceeds something like this:
Again, the
$!
makes no difference here: the pattern match onL1
in the instance for sums will force thecase MkA x ..
anyway.But now consider the case for a datatype with a single constructor and a single field:
Now we are doomed if we do and doomed if we don't. In the library as it stands, with the
$!
, we getNotice what is happening here: since the
x
is not protected by any constructor (bothM1
andK
are newtypes), this will end up forcingx
. This is bad, becausenothunks
should not result in any evaluation happening. But we cannot remove the!
either; if we do, we get something likeIn other words, we will report thunks when there aren't any.
I'm not entirely sure what the right solution is here, or if there even is one. Ideally the
K
constructor from GHC generics would not be a newtype; that would solve the problem, but is of course hardly a practical solution.I think for now we should probably just document that the generic instance does not work for single-constructer-single-argument types. Whether or not that means changing the code (removing the bang in the definition of
fp
) I'm not totally sure about. As it stands,nothunks
may force some evaluation to happen for such types, but will not result in confusing error messages. If we remove it, then using the generic instance for such types will result in thunks being found where there aren't really any, but at least you would be aware that something is amiss. Would appreciate an independent opinion here.The text was updated successfully, but these errors were encountered: