在我的程序上运行 hlint 时,它报告了一个错误
\x -> [x]
并提出了另一种形式
(: [])
根据关于第一种形式的 hlint有什么错误,因此我为什么要使用(可读性较差的)第二个选项?
编辑
(在问题中明确添加了 hlint)
我的问题不在于从词汇的角度来看有什么区别(我确实理解它们)。我的问题是我不明白为什么 hlint 将其标记为错误。例如,懒惰有区别吗?此外,为什么hlint之前的想法是错误\x -> Just x
的,而只会提出警告。
一个常见问题,我刚刚在HLint 手册中添加了一个答案。它说:
每个提示都有一个严重级别:
- 错误 - 例如
concat (map f x)
建议concatMap f x
作为“错误”严重性提示。从风格的角度来看,您应该始终将concat
和的组合map
替换为concatMap
。请注意,这两个表达式是等效的 - HLint 报告的是样式错误,而不是代码中的实际错误。- 警告- 例如
x !! 0
建议head x
作为“警告”严重性提示。通常head
是表达列表第一个元素的一种更简单的方法,尤其是在您以归纳方式处理列表时。但是,在表达式f (x !! 4) (x !! 0) (x !! 7)
中,将中间参数替换为 head 会使模式更难遵循,并且可能是个坏主意。警告提示通常是值得的,但不应盲目应用。错误和警告之间的区别是个人品味之一,通常是我的个人品味。如果你已经对 Haskell 风格有很好的理解,你应该忽略其中的区别。如果您是初学者 Haskell 程序员,您可能希望在警告提示之前关注错误提示。
虽然区别在于个人品味,但有时我会改变主意。查看此线程中的两个示例,(:[])
似乎是一个相对“复杂”的提示-您正在分解 to 的语法糖[x]
,x:[]
如果您从不进行模式匹配,则在某些方面将列表的抽象剥离为通用容器它。相比之下\x -> Just x
,Just
总是似乎是个好主意。因此,在 HLint-1.8.43(刚刚发布)中,我将第一个警告,第二个错误。
没有真正的区别。HLint 关注风格问题;最终,它们只是关于如何使您的代码看起来更好的提示。
通常,将 lambda 与类似的构造函数或函数一起使用是多余的,并且会使代码更难阅读。举个极端的例子,以构造函数 likeJust
为例:Just
比较\ x -> Just x
. 这些是等价的,但第二个版本肯定会让事情变得更加混乱!作为一个更接近的例子,大多数人会选择(+ 1)
over \ x -> x + 1
。
在您的特定情况下,这是一个不同的故事,因为列表具有特殊的语法。因此,如果您\ x -> [x]
更喜欢该版本,请保留它。但是,一旦您习惯了操作符部分,您可能会发现该(: [])
版本很容易阅读(如果不是更容易的话),因此即使现在也要考虑使用它。
我可能会考虑使用return
orpure
为此:
ghci> return 0 :: [Int]
[0]
ghci> import Control.Applicative
ghci> pure 0 :: [Int]
[0]
我需要包含类型注释 ( :: [Int]
) 因为我在 GHCi 中工作。在一堆其他代码中间,您可能不需要它。