1
votes

I was playing around with a very simple haskell program and forgot a quote in a function call (last lookup call in the following sample code).

import Data.List
main :: IO ()
main = do
    let sum = sumAllOddSquaresSmallerThan 100
    print sum
    let testMap = [(4,"Foo"), (2,"Bar"), (1,"Baz")]
    print $ lookup' testMap 2

sumAllOddSquaresSmallerThan :: (Ord a, Integral a) => a -> a
sumAllOddSquaresSmallerThan n = sum(takeWhile (<n) (filter odd (map (^2) [1..])))

lookup' :: Eq a => [(a,b)] -> a -> b
lookup' [] _ = error("key not in the list")
lookup' ((x',y'):xs) x = if x' == x then y' else lookup xs x

The error message given by GHC is the following one :

CompilerErrorTest.hs:12:70:
    Could not deduce (Integral b1) arising from a use of ‘^’
    from the context (Ord a, Integral a)
      bound by the type signature for
                 sumAllOddSquaresSmallerThan :: (Ord a, Integral a) => a -> a
      at CompilerErrorTest.hs:11:32-60
    The type variable ‘b1’ is ambiguous
    Note: there are several potential instances:
      instance Integral Int -- Defined in ‘GHC.Real’
      instance Integral Integer -- Defined in ‘GHC.Real’
      instance Integral GHC.Types.Word -- Defined in ‘GHC.Real’
    In the first argument of ‘map’, namely ‘(^ 2)’
    In the second argument of ‘filter’, namely ‘(map (^ 2) [1 .. ])’
    In the second argument of ‘takeWhile’, namely
      ‘(filter odd (map (^ 2) [1 .. ]))’

CompilerErrorTest.hs:12:71:
    Could not deduce (Num b1) arising from the literal ‘2’
    from the context (Ord a, Integral a)
      bound by the type signature for
                 sumAllOddSquaresSmallerThan :: (Ord a, Integral a) => a -> a
      at CompilerErrorTest.hs:11:32-60
    The type variable ‘b1’ is ambiguous
    Note: there are several potential instances:
      instance Num Double -- Defined in ‘GHC.Float’
      instance Num Float -- Defined in ‘GHC.Float’
      instance Integral a => Num (GHC.Real.Ratio a)
        -- Defined in ‘GHC.Real’
      ...plus three others
    In the second argument of ‘(^)’, namely ‘2’
    In the first argument of ‘map’, namely ‘(^ 2)’
    In the second argument of ‘filter’, namely ‘(map (^ 2) [1 .. ])’

CompilerErrorTest.hs:17:60:
    Could not deduce (a ~ [([(a, b)], b0)])
    from the context (Eq a)
      bound by the type signature for
                 lookup' :: Eq a => [(a, b)] -> a -> b
      at CompilerErrorTest.hs:15:12-36
      ‘a’ is a rigid type variable bound by
          the type signature for lookup' :: Eq a => [(a, b)] -> a -> b
          at CompilerErrorTest.hs:15:12
    Relevant bindings include
      x :: a (bound at CompilerErrorTest.hs:17:22)
      xs :: [(a, b)] (bound at CompilerErrorTest.hs:17:18)
      y' :: b (bound at CompilerErrorTest.hs:17:14)
      x' :: a (bound at CompilerErrorTest.hs:17:11)
      lookup' :: [(a, b)] -> a -> b (bound at CompilerErrorTest.hs:16:1)
    In the second argument of ‘lookup’, namely ‘x’
    In the expression: lookup xs x

To make matter worse, I first tried the example in FP Complete online haskell IDE which was hiding the last two lines of the error message (I hadn't noticed the ... near the end of the message at first)

Could someone please explain why GHC gives these errors in the unrelated sumAllOddSquaresSmallerThan function and how I could have narrowed the source of the mistake rapidly ?

1
The way I would debug this is that I would comment all the functions and try un-commenting each function. That will show that your lookup' function has the problem. And then from there it's easier to debug. That being said, haskell supports good interactive development. So as you as you write a single function you can load them up in ghci and verify that for yourself if it works or not. You don't want to write a 1000 lines code and then try to compile it. :)Sibi
I don't think that this is the expected behavior for GHC (it might be a bug?) - as these are really not related at all - but I am sure that someone will prove me wrong and I did not see some simple explanation ;)Random Dev
This looks as a GHC regression, IMHO. The code above in ghc-7.6.3 gives only two errors around the lookup line, which looks fine. Instead, ghc-7.8.3 generates the unrelated errors shown above. I wonder if ghc-7.10.1 does the same.chi
Also ghc-7.8.4 generates three errors.Sibi
I've just tried ghci-7.10.1. It works fine: only one error is being produced in the relevant line.chi

1 Answers

0
votes

The fix seems to update ghc to the 7.10.1 version whose error message is much more helpful in locating the bug...but it might not be an option for everyone.