Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid warning Defaulting the following constraint(s) to type `Integer'

Tags:

haskell

I have defined the following function to reverse a list of Int or string:

myReverse :: [a] -> [a]
myReverse [] = []
myReverse (x:xs) = (myReverse xs) ++ [x]

My test with hspec:

 describe "myReverse" $ do
  it "returns the inversed list of the given list" $ do
   myReverse [1,2,3,4] `shouldBe` [4,3,2,1]

  it "returns the inversed string of the given string" $ do
   myReverse "A man, a plan, a canal, panama!" `shouldBe` "!amanap ,lanac a ,nalp a ,nam A"

Like this I get the warning

tests/OneToTenSpec.hs:69:24:
    Warning: Defaulting the following constraint(s) to type `Integer'
               (Eq a0)
                 arising from a use of `shouldBe' at tests/OneToTenSpec.hs:69:24-33
               (Num a0)
                 arising from the literal `1' at tests/OneToTenSpec.hs:69:15
               (Show a0)
                 arising from a use of `shouldBe' at tests/OneToTenSpec.hs:69:24-33
    In a stmt of a 'do' block:
      myReverse [1, 2, 3, 4] `shouldBe` [4, 3, 2, 1]
    In the second argument of `($)', namely
      `do { myReverse [1, 2, ....] `shouldBe` [4, 3, ....] }'
    In a stmt of a 'do' block:
      it "returns the inversed list of the given list"
      $ do { myReverse [1, 2, ....] `shouldBe` [4, 3, ....] }

So I made the following change on the test

myReverse [1 :: Int,2,3,4] `shouldBe` [4,3,2,1]

Is there is another way to avoid this warning than defining the type of an element of the list ?

like image 729
La Chamelle Avatar asked Feb 19 '14 20:02

La Chamelle


1 Answers

Not with numeric literals. Since literals have the type Num a => a and we're feeding it to a function that's polymorphic in a, there are no hints as to what to resolve a to.

The good news is that this is exactly how defaulting is meant to work and you have nothing to worry about! The warning is annoying though, I can think of two ways to avoid it

  1. Use explicit type signatures
  2. Don't use numeric literals

2 will probably be the best in your scenario, we know from the type that the type of element can't impact its function, so you're free to use Bool

 myReverse [True, False] `shouldBe` [False, True]

As an aside your current implementation is O(n^2) and O(n) is possible, I'll leave it to you to figure out how though :)

like image 123
Daniel Gratzer Avatar answered Sep 27 '22 16:09

Daniel Gratzer