对GHC风格的影响 [英] Impact on style of GHC -Wall
问题描述
使用 -Wall
启用GHC警告是良好的做法。然而,我发现修复这些警告对一些类型的代码构造有负面影响。
示例1:
使用等效于<$ c如果我没有明确使用 _< - f
表单,则$ c> f>> 将生成警告:
警告:do-notation语句抛弃了Char类型的结果。
通过说_< - f,
或使用标志-fno-warn-unused-do-bind
抑制此警告
我知道我可以忘记用 f
的结果做一些事情。然而,忽略结果(在解析器中很常见)是合理的。使用>>
时没有警告,对不对?使用 _< -
比它应该重。
示例2: / p>
使用可见函数的同名命名模式变量将给出:
警告:`map'的绑定会影响现有绑定
从Prelude导入
当使用记录语法时,名称空间迅速被污染,这种情况越来越严重。解决方案是在模式表达式中给出备用名称。所以我最后使用一个不太适当的名称,只是为了避免警告。我不觉得这是一个足够好的原因。
我知道我可以使用 -fno-warn -...
选项,但是我应该坚持 -Wall
毕竟?
p> 示例1:
我已经学会了以适用风格编写解析器 - 它们更加简洁。例如,而不是:
funCallExpr :: Parser AST
funCallExpr = do
func <
token(
arg< - expr
token)
return $ FunCall func arg
我改为:
funCallExpr :: Parser AST
funCallExpr = FunCall< $> atom< * token"(* expr< * token)
<
示例2:
如果您不喜欢该警告,是的,我发现警告也有点刺激。但它救了我几次。
它与命名约定有关。我喜欢保持模块相当小,并保持大多数导入合格(除了注释导入像 Control.Applicative
和 Control.Arrow
)。这保持名称冲突的机会很低,它只是使事情很容易使用。 hothasktags
使这种风格可以容忍,如果你正在使用标签。
如果你只是模式匹配字段与相同名称,您可以使用 -XNamedFieldPuns
或 -XRecordWildCards
重新使用该名称:
data Foo = Foo {baz :: Int,bar :: String}
- RecordWildCards
doubleBaz :: Foo - > int
doubleBaz(Foo {..})= baz * baz
- NamedFieldPuns
reverseBar :: Foo - > String
reverseBar(Foo {bar})= reverse bar
用于记录标签的匈牙利前缀:
data Foo = Foo {fooBaz :: Int,fooBar :: String}
但是,记录在Haskell中不起作用。无论如何,保持你的模块小,你的抽象紧,这不应该是一个问题。将其视为警告,说明 simplifiedyyy,man 。
It is considered good practice to enable GHC warnings with -Wall
. However, I've found out that fixing those warnings has a negative effect for some types of code constructs.
Example 1:
Using the do-notation equivalent of f >>
will generate a warning if I don't explicitly use the _ <- f
form:
Warning: A do-notation statement discarded a result of type Char.
Suppress this warning by saying "_ <- f",
or by using the flag -fno-warn-unused-do-bind
I understand that I can forget to do something with the result of f
. However, it is legitimate to ignore the result (very common in parsers). There is no warning when using >>
, right? Using _ <-
is heavier than it should.
Example 2:
Naming a pattern variable with the same name of a visible function will give:
Warning: This binding for `map' shadows the existing binding
imported from Prelude
This is getting worse when using record syntax as namespace gets polluted quickly. The solution is to give an alternate name in the pattern expression. So I end up using a less appropriate name just to avoid a warning. I don't feel it's a good-enough reason.
I know I can use -fno-warn-...
options but should I stick with -Wall
after all?
Example 1:
I have re-learned to write parsers in Applicative style -- they are much more concise. Eg, instead of:
funCallExpr :: Parser AST
funCallExpr = do
func <- atom
token "("
arg <- expr
token ")"
return $ FunCall func arg
I instead write:
funCallExpr :: Parser AST
funCallExpr = FunCall <$> atom <* token "(" <*> expr <* token ")"
But what can I say, if you don't like the warning, disable it as it suggests.
Example 2:
Yeah I find that warning a bit irritating as well. But it has saved me a couple times.
It ties into naming conventions. I like to keep modules pretty small, and keep most imports qualified (except for "notation" imports like Control.Applicative
and Control.Arrow
). That keeps the chances of name conflict low, and it just makes things easy to work with. hothasktags
makes this style tolerable if you are using tags.
If you are just pattern matching on a field with the same name, you can use -XNamedFieldPuns
or -XRecordWildCards
to reuse the name:
data Foo = Foo { baz :: Int, bar :: String }
-- RecordWildCards
doubleBaz :: Foo -> Int
doubleBaz (Foo {..}) = baz*baz
-- NamedFieldPuns
reverseBar :: Foo -> String
reverseBar (Foo {bar}) = reverse bar
Another common convention is to add a hungarian prefix to record labels:
data Foo = Foo { fooBaz :: Int, fooBar :: String }
But yeah, records are no fun to work with in Haskell. Anyway, keep your modules small and your abstractions tight and this shouldn't be a problem. Consider it as a warning that says simplifyyyy, man.
这篇关于对GHC风格的影响的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!