coercion errors don't always mention that data constructors are not in scope
Suppose a library defines a newtype
with a nominal
type parameter:
{-# LANGUAGE RoleAnnotations #-}
module Lib where
type role LibIdentity nominal
newtype LibIdentity a = LibIdentity a
(in my code, that newtype
is ExceptT
, whose last argument is inferred to be nominal
)
In a different module, I also define a newtype
, and then I try to use coerce
to remove some of the newtype
wrappers. Unfortunately I forgot to import LibIdentity
's data constructor, and so the coercions fail. Sometimes, the error message helpfully explains that I need that import... but sometimes it doesn't!
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Local where
import Data.Coerce (coerce)
import Lib (LibIdentity)
newtype LocalIdentity a = LocalIdentity a
-- error:
-- • Couldn't match representation of type ‘()’
-- with that of ‘LibIdentity ()’
-- arising from a use of ‘coerce’
-- The data constructor ‘Lib.LibIdentity’
-- of newtype ‘LibIdentity’ is not in scope
helpfulError :: LocalIdentity (LibIdentity ()) -> LocalIdentity ()
helpfulError = coerce
-- error:
-- • Couldn't match type ‘LocalIdentity ()’ with ‘()’
-- arising from a use of ‘coerce’
difficultError :: LibIdentity (LocalIdentity ()) -> LibIdentity ()
difficultError = coerce
Expected: both uses of coerce
remind me to import the data constructor of LibIdentity
.
Observed: only helpfulError
reminds me, while difficultError
doesn't.
(in my code, the coerce
is generated by GeneralizedNewtypeDeriving
and the error message does not include the type whose data constructor needs to be imported, making it quite difficult to guess how to fix the error)
Trac metadata
Trac field | Value |
---|---|
Version | 8.6.1 |
Type | FeatureRequest |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |