hlint
hlint copied to clipboard
Hint `Redundant <&>` suggests code obfuscation
main = do
e <- getContents <&> pExp . myLexer >>= \case
Left err -> do
putStrLn err
exitFailure
Right e -> pure e
This triggers this linter warning:
Warning: Redundant <&>
Found:
getContents <&> pExp . myLexer
>>=
\case
Left err
-> do putStrLn err
exitFailure
Right e -> pure e
Perhaps:
getContents
>>=
(\case
Left err
-> do putStrLn err
exitFailure
Right e -> pure e)
. pExp . myLexer
Clearly, you do not want such a refactoring. (Imagine the case distinction was even larger.)
In fact the whole point of using <&> in my original expression is that I can write a monadic case in a readable way without introducing a throw-away variable.
There might be similar problems with similar hints.
They hardly take the size of expressions into account, or pipelining styles.
In general, I tend to ignore all hints that suggest stuff like "fuse map into foldr" or any form of "fuse fmap into bind", etc, as they all often have similar issues
This may point to a systematic problem of hlint: it suggests mathematically correct refactorings, but code has two consumers, the compiler, and the human reader, and a refactoring must be sound for both of them.
Perhaps a reasonable rule is: if the suggestion requires extra brackets, avoid it. This is however not very trivial to implement, and I'm not sure if it should always be applied.