You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This isn't a bug report, more like a documentation attempt. I've been repeatedly hitting speed-bumps when trying to introduce custom project-specific HLint rules; at least to me, rule writing feels harder than it should be. Perhaps some hints could help future me, or others.
I'm assuming a flow like the following.
Spot a "popular" but flawed code pattern in a codebase.
Write an improved replacement.
Write a hlint rule, for the double-duty:
statically find the pattern in existing code for mass-change;
prevent popping in again in the future.
Apply, build, test, commit... continue as usual.
Alas, something goes wrong at step 3. The new rule doesn't trigger, No hints. What do?
Conventional first steps
Skim the output of --help, discover and try --verbose & --show.
Minimize a self-contained small source snippet where your rule should trigger. There's no need for it to typecheck, it only has to parse as well-formed Haskell syntax. Test your rule on it. Experiment.
(That's generically-applicable troubleshooting advice; as such, I'd assume it's well-known anyway. However, I'd been wrong.)
HLint-specific gotchas
hlint considers only single-letter identifiers as rules' variables. Anything longer will match literally.
hlint has special interpretations for (), $, (.) and possibly other haskell syntax.
know thy yaml syntax, and its symbols. Try Dhall if unsure.
Renamed as imports
The AST that HLint works on, comes after GHC renamer (which is the chunk of compiler logic that resolves names). This means that your rules might need to refer to identifiers by fully-qualified original names.
# .hlint.yaml rules file#-- won't trigger:warn:
lhs: Log.error a >> Log.exception brhs: Log.exceptionCtx a b#-- won't trigger either:warn:
lhs: error a >> exception brhs: exceptionCtx a b#-- this one does work!warn:
lhs: AcmeProject.Logger.error a >> AcmeProject.Logger.exception brhs: AcmeProject.Logger.exceptionCtx a b
The text was updated successfully, but these errors were encountered:
I agree better documentation is needed especially for scoping. Regarding your example, I think the second hint (with unqualified names) should trigger - it doesn't make much sense that it doesn't.
This isn't a bug report, more like a documentation attempt. I've been repeatedly hitting speed-bumps when trying to introduce custom project-specific HLint rules; at least to me, rule writing feels harder than it should be. Perhaps some hints could help future me, or others.
I'm assuming a flow like the following.
Alas, something goes wrong at step 3. The new rule doesn't trigger,
No hints
. What do?Conventional first steps
Skim the output of
--help
, discover and try--verbose
&--show
.Consult the README, several times if impatient.
Minimize a self-contained small source snippet where your rule should trigger. There's no need for it to typecheck, it only has to parse as well-formed Haskell syntax. Test your rule on it. Experiment.
(That's generically-applicable troubleshooting advice; as such, I'd assume it's well-known anyway. However, I'd been wrong.)
HLint-specific gotchas
hlint considers only single-letter identifiers as rules' variables. Anything longer will match literally.
hlint has special interpretations for
()
,$
,(.)
and possibly other haskell syntax.know thy yaml syntax, and its symbols. Try Dhall if unsure.
Renamed
as
importsThe AST that HLint works on, comes after GHC renamer (which is the chunk of compiler logic that resolves names). This means that your rules might need to refer to identifiers by fully-qualified original names.
Example
The text was updated successfully, but these errors were encountered: