Impact on style of GHC -Wall

前端 未结 6 490
囚心锁ツ
囚心锁ツ 2021-02-02 10:16

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 c

6条回答
  •  暗喜
    暗喜 (楼主)
    2021-02-02 10:50

    I think that use of -Wall may lead to less readable code. Especially, if it is doing some arithmetics.

    Some other examples, where the use of -Wall suggests modifications with worse readability.

    (^) with -Wall requires type signatures for exponents

    Consider this code:

    norm2 x y = sqrt (x^2 + y^2)
    main = print $ norm2 1 1
    

    With -Wall it gives two warnings like this:

    rt.hs:1:18:
        Warning: Defaulting the following constraint(s) to type `Integer'
                 `Integral t' arising from a use of `^' at rt.hs:2:18-20
        In the first argument of `(+)', namely `x ^ 2'
        In the first argument of `sqrt', namely `(x ^ 2 + y ^ 2)'
        In the expression: sqrt (x ^ 2 + y ^ 2)
    

    Writing (^(2::Int) everywhere instead of (^2) is not nice.

    Type signatures are required for all top-levels

    When writing quick and dirty code, it's annoying. For simple code, where there are at most one or two data types in use (for exapmle, I know that I work only with Doubles), writing type signatures everywhere may complicate reading. In the example above there are two warnings just for the lack of type signature:

    rt.hs:1:0:
        Warning: Definition but no type signature for `norm2'
                 Inferred type: norm2 :: forall a. (Floating a) => a -> a -> a
    ...
    
    rt.hs:2:15:
        Warning: Defaulting the following constraint(s) to type `Double'
                 `Floating a' arising from a use of `norm2' at rt.hs:2:15-23
        In the second argument of `($)', namely `norm2 1 1'
        In the expression: print $ norm2 1 1
        In the definition of `main': main = print $ norm2 1 1
    

    As a distraction, one of them refers to the line different from the one where the type signature is needed.

    Type signatures for intermediate calculations with Integral are necessary

    This is a general case of the first problem. Consider an example:

    stripe x = fromIntegral . round $ x - (fromIntegral (floor x))
    main = mapM_ (print . stripe) [0,0.1..2.0]
    

    It gives a bunch of warnings. Everywhere with fromIntegral to convert back to Double:

    rt2.hs:1:11:
        Warning: Defaulting the following constraint(s) to type `Integer'
                 `Integral b' arising from a use of `fromIntegral' at rt2.hs:1:11-22
        In the first argument of `(.)', namely `fromIntegral'
        In the first argument of `($)', namely `fromIntegral . round'
        In the expression:
                fromIntegral . round $ x - (fromIntegral (floor x))
    

    And everyone knows how often one needs fromIntegral in Haskell...


    There are more cases like these the numeric code risks to become unreadable just to fulfill the -Wall requirements. But I still use -Wall on the code I'd like to be sure of.

提交回复
热议问题