Hlint建议:使用uncurry

4
我有这行代码:

我有这行代码:

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

Hlint建议我用

替换它。
map (uncurry (flatTorus n)) gridUV

这个建议的动机是什么?仅仅为了简短,还是其他方面(性能)?因为虽然第二个代码更短,但我发现第一个代码更易于阅读。
实际上,我的问题更加普遍,因为这只是其中一个例子:Hlint的建议是否通常仅基于简短的动机,还是有其他改进在建议背后?

1
更易读我猜:如果你知道uncurry的作用,那么人们就不必思考正在发生什么。我还认为hlint建议使用map (uncurry (flatTorus n)) gridUV(多加一对括号)。 - Willem Van Onsem
5
我认为 hlint 的建议既考虑到代码的简洁性又注意到可读性。其中一些建议可能会在社区中得到广泛认同,而其他建议(比如这个)则不一定。就个人而言,我并没有发现第二段代码比第一段要好多少;它们可以说是几乎等价的。也许 hlint 应该为其建议提供一个权重。 - chi
1
@StéphaneLaurent:使用x!!0head x都不是很优雅。最好使用模式匹配,因为不能保证列表有元素。实际上,应该避免使用headtail(!!)length这些函数。 - Willem Van Onsem
6
@StéphaneLaurent 我会写成 let [a,b,c] = x in Vertex3 a b c - Li-yao Xia
5
@Li-yaoXia:我认为你需要保留一个(可能为空的)尾部。但是你可以像这样编写:f (x0:x1:x2:_) = Vertex x0 x1 x2; f _ = <其他内容> - Willem Van Onsem
显示剩余9条评论
2个回答

2

我认为 Hlint 更喜欢使用 uncurry,因为它可以给你一个回调的不变表示。Lambda表达式本质上对表示形式比较敏感,因为

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

等同于

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

尽管它们在文本上有所不同,但使用uncurry可以使读者免于在脑中进行α等价性操作(例如,识别上述两个表达式是相同的),但随之而来的是需要记住组合器词汇的认知负荷。最终,这是一个品味问题。


1
这些实际上并不完全等价。
(\(x, y) -> (,) x y) undefined = undefined
uncurry (,) undefined = (undefined, undefined)

如果你使用uncurry,建议谨慎考虑。需要思考这种额外的惰性是否会有帮助、伤害或者没有任何影响。


1
HLint 的输出实际上包括上面示例中的“注意:增加惰性”。 - Neil Mitchell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接