在我的程序上运行hlint时,它报告
的错误\x -> [x]
并建议替代形式
(: [])
根据关于第一种形式的hlint有什么错误,因此为什么我应该使用(不太可读)第二种形式?
(明确地向问题添加了hlint)
在词汇的观点上,我的问题不在于差异是什么(我确实理解它们两者)。我的问题是我不明白为什么hlint将其标记为错误。有没有例如懒惰的差异?此外,为什么先前认为hlint为错误,而\x -> Just x
仅引发警告。
答案 0 :(得分:14)
一个常见问题,我刚刚在HLint manual中添加了答案。它说:
每个提示都有严重级别:
- 错误 - 例如
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程序员,您可能希望在警告提示之前关注错误提示。
虽然不同之处在于个人品味,但有时我会改变主意。看一下这个帖子中的两个例子,(:[])
似乎是一个相对“复杂”的提示 - 你正在将[x]
的句法糖分解为x:[]
,这在某些方面正在剥离将列表抽象为通用容器,如果您从未对其进行模式匹配。相比之下,\x -> Just x
到Just
似乎总是一个好主意。因此,在HLint-1.8.43(刚刚发布)中,我首先发出警告,第二次发生错误。
答案 1 :(得分:12)
没有真正的区别。 HLint关注风格问题;最终,它们只是提示如何使代码看起来更好。
通常,使用带有构造函数或类似函数的lambda是多余的,并使代码更难读取。作为一个极端的例子,以Just
之类的构造函数为例:将Just
与\ x -> Just x
进行比较。这些是等价的,但第二个版本肯定会让事情变得更加混乱!再举一个例子,大多数人会选择(+ 1)
而不是\ x -> x + 1
。
在您的特定情况下,它是一个不同的故事,因为列表具有特殊的语法。因此,如果您更喜欢\ x -> [x]
版本,请保留它。但是,一旦你习惯了操作符部分,你可能会发现(: [])
版本很容易 - 如果不是更容易 - 阅读,所以现在考虑使用它。
答案 2 :(得分:7)
我可能会考虑使用return
或pure
:
ghci> return 0 :: [Int]
[0]
ghci> import Control.Applicative
ghci> pure 0 :: [Int]
[0]
我需要包含类型注释(:: [Int]
)因为我在GHCi工作。在一堆其他代码的中间,您可能不需要它。