4

I have this line of code:

map (\(u,v) -> flatTorus n u v) gridUV

Hlint suggests me to replace it with

map (uncurry (flatTorus n)) gridUV

What is the motivation of this suggestion ? Is it for shortness only, or something else (performance) ? Because though it is longer, I find the first code more easy to read.

In fact my question is more general,, because this is just an example among others: does Hlint suggestions are generally based on a shortness motivation only or are there other improvements behind the suggestions ?

Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
  • 1
    More readability I guess: if you know what `uncurry` does, there is less that people have to think about what is going on. I also think that `hlint` suggests `map (uncurry (flatTorus n)) gridUV` (with an extra pair of brackets). – Willem Van Onsem Mar 15 '18 at 12:44
  • Yes sorry, I forgot the brackets. I edit. – Stéphane Laurent Mar 15 '18 at 12:46
  • 5
    I think `hlint` suggestions are guided by both shortness and readability. Some of them probably would find a strong agreement in the community. Others, like this one, not so much. Personally, I find the second code not much better than the first one; I'd say they are nearly equivalent. Maybe `hlint` should also provide a weight to its suggestions. – chi Mar 15 '18 at 13:04
  • Yes. One suggestion I really don't like is use `head x` instead of `x!!0`. I have not been able to disable this suggestion in VScode. – Stéphane Laurent Mar 15 '18 at 13:10
  • 1
    @StéphaneLaurent: well using `x!!0` and `head x` are both not very elegant. You better use pattern matching for that, since it is not guaranteed that a list has an element. In fact `head`, `tail`, `(!!)`, and `length` are functions that should be avoided. – Willem Van Onsem Mar 15 '18 at 13:14
  • @WillemVanOnsem Yes but for example sometimes I do `Vertex3 (x!!0) (x!!1) (x!!2)`. It would be silly to use `head x` here. – Stéphane Laurent Mar 15 '18 at 13:17
  • 6
    @StéphaneLaurent I would write `let [a,b,c] = x in Vertex3 a b c` – Li-yao Xia Mar 15 '18 at 13:20
  • 5
    @Li-yaoXia: well I think you have to keep a (possibly empty tail). But you can it like: `f (x0:x1:x2:_) = Vertex x0 x1 x2; f _ = ` – Willem Van Onsem Mar 15 '18 at 13:26
  • Why not write `[ flatTorus n u v | (u, v) <- gridUV ]`? – Elmex80s Mar 15 '18 at 14:34
  • `hlint` does provide weights to its suggestions - this one is merely a suggestion rather than a warning. I regularly trim old suggestions based on feedback to try and follow the preferences of the community. – Neil Mitchell Mar 24 '18 at 17:48
  • @StéphaneLaurent you can disable extensions with a `.hlint.yaml` in the root directory. See https://github.com/ndmitchell/hlint/blob/master/.hlint.yaml#L59 – Neil Mitchell Mar 24 '18 at 17:49
  • @NeilMitchell Thanks! I will check that. Previously I used Atom and I was able to configure. But my Atom does not work anymore :-( – Stéphane Laurent Mar 24 '18 at 17:59
  • @NeilMitchell `- ignore: {name: Use head, within: HLint}` does not work. I put `.hlint.yaml` in the root directory of my stack project. Is it the right place to put it? – Stéphane Laurent Mar 24 '18 at 18:12
  • 1
    @NeilMitchell Ah ok, it works like this: `- ignore: {name: Use head}`. Fantastic! – Stéphane Laurent Mar 24 '18 at 18:18

2 Answers2

2

I think Hlint prefers using uncurry because it gives you an invariant representation of the callback. Lambda expressions are inherently sensitive to representation, since

\(u, v) -> flatTorus n u v

is equivalent to

\(x, y) -> flatTorus n x y

even though they are textually different.

Using uncurry frees readers of the cognitive load of doing alpha equivalence in their head (e.g., recognizing that the above two expressions are the same), but then saddles them with the cognitive load of having to remember a vocabulary of combinators. Ultimately, it's a matter of taste.

Fried Brice
  • 769
  • 7
  • 20
1

These are not actually quite equivalent.

(\(x, y) -> (,) x y) undefined = undefined
uncurry (,) undefined = (undefined, undefined)

Do you should take any suggestion to use uncurry with a grain of salt. Think about whether that extra laziness will help, hurt, or make no difference.

dfeuer
  • 48,079
  • 5
  • 63
  • 167