Open danidiaz opened 4 years ago
Added a type error for mismatched names in db0194449e5a7b327111ddb80b20e066ddc1251e, but more could be added.
For example, the error for forgetting to add the alias for the last branch of a sum type is:
* No instance for (ByOtherNames.AliasTree
'[]
(M1
C
('MetaCons "Ee" 'PrefixI 'False)
(S1
('MetaSel
'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy)
(Rec0 Int)))
'[])
And the error for forgetting to add the alias for the last field of a record type is:
tests\tests.hs:38:5: error:
* No instance for (ByOtherNames.AliasTree
'[]
(M1
S
('MetaSel
('Just "ee")
'NoSourceUnpackedness
'NoSourceStrictness
'DecidedLazy)
(Rec0 Int))
'[])
Which could be better.
Added a type error for missing final aliases in 4985c0ab8f32ddb87aa2687f39c8e0a3d2aeb98f.
Other possible errors to improve:
tests\tests.hs:38:5: error:
* No instance for (ByOtherNames.AliasTree
middle3
(M1
S
('MetaSel
'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy)
(Rec0 Bool))
middle0)
arising from a use of `fieldAliases'
* No instance for (ByOtherNames.AliasTree
'["Bb", "Cc", "Dd", "Ee"]
(M1
C
('MetaCons "Bb" 'PrefixI 'True)
(S1
('MetaSel
('Just "fofofo")
'NoSourceUnpackedness
'NoSourceStrictness
'DecidedLazy)
(Rec0 Bool)))
Sometimes the presence of the functional dependency gets in the way of improving the errors:
These two instances can't coexist:
instance AliasTree before tree '[] => AliasTree before (D1 x (C1 y tree)) '[] where
parseAliasTree as =
let (aliases', as') = parseAliasTree as
in (Record aliases', as')
-- doesn't work because of the functional dependency :(
-- instance ExcessAliasError name => AliasTree before (D1 x (C1 y tree)) (name : names) where
Sometimes the presence of the functional dependency gets in the way of improving the errors
This is even worse in the case of ByOtherNamesH
. There, the dependency needs to be bidirectional in order for type inference to work, but it precludes all the custom error messages implemented in ByOtherNames
.
type ToAliases :: [(Symbol, [Type])] -> (Type -> Type) -> [(Symbol, [Type])] -> Constraint
-- | The second functional dependency is needed for type inference to work.
class ToAliases before rep after | before rep -> after, after rep -> before where
parseAliasTree :: AliasList before a h -> (Aliases rep a h, AliasList after a h)
type ToBranchFields :: [Type] -> (Type -> Type) -> [Type] -> Constraint
-- | The second functional dependency is needed for type inference to work.
class ToBranchFields before rep after | before rep -> after, after rep -> before where
parseBranchFields :: SlotList before h -> (BranchFields rep h, SlotList after h)
Look in A story told by Type Errors for inspiration.
Here's what the GHC User Guide says about them.