When running hlint over my program it reported an error for
\x -> [x]
and suggested the alternative form
(: [])
What is there erroneous according to hlint about the first form, and thus why should I use the (less readable) second option?
(added hlint explicitly to the question)
My question lies not so much with what the difference is (I do understand both of them) in lexical point of view. My problem is that I do not understand why hlint is marking it as an error. Is there for example a difference in laziness? Furthermore why is the previous thought of as erroneous by hlint while \x -> Just x
raises only a warning.
A common question, to which I've just added an answer in the HLint manual. It says:
Every hint has a severity level:
- Error - for example
concat (map f x)
suggestsconcatMap f x
as an "error" severity hint. From a style point of view, you should always replace a combination ofconcat
andmap
withconcatMap
. Note that both expressions are equivalent - HLint is reporting an error in style, not an actual error in the code.- Warning - for example
x !! 0
suggestshead x
as a "warning" severity hint. Typicallyhead
is a simpler way of expressing the first element of a list, especially if you are treating the list inductively. However, in the expressionf (x !! 4) (x !! 0) (x !! 7)
, replacing the middle argument with head makes it harder to follow the pattern, and is probably a bad idea. Warning hints are often worthwhile, but should not be applied blindly.The difference between error and warning is one of personal taste, typically my personal taste. If you already have a well developed sense of Haskell style, you should ignore the difference. If you are a beginner Haskell programmer you may wish to focus on error hints before warning hints.
While the difference is personal taste, sometimes I change my mind. Looking at the two examples in this thread, (:[])
seems a relatively "complex" hint - you are breaking down the syntactic sugar of [x]
to x:[]
, which in some ways is peeling through the abstraction of a list as a generic container, if you never pattern match on it. In contrast \x -> Just x
to Just
always seems like a good idea. Therefore, in HLint-1.8.43 (just released) I have made the first a warning, and the second an error.
There is no real difference. HLint concerns itself with style issues; ultimately, they are just hints on how to make your code look better.
In general, using a lambda with a constructor or function like that is redundant and makes the code harder to read. As an extreme example, take a constructor like Just
as an example: compare Just
to \ x -> Just x
. These are equivalent but the second version certainly makes things more confusing! As a closer example, most people would choose (+ 1)
over \ x -> x + 1
.
In your particular case, it's a different story because lists have special syntax. So if you like the \ x -> [x]
version better, just keep it. However, once you become used to operator sections, it's likely you'll find the (: [])
version as easy--if not easier--to read, so consider using it even now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With