Haskell – How to work with assertEqual with parameterized types

haskellhunittesting

I'm trying to do the exercises in Real World Haskell in a TDD fashion, using HUnit. As you probably guessed I haven't gotten far yet so I'm an absolute beginner when it comes to Haskell. Given the following code how can I resolve the following error ghci produces:

Ambiguous type variable a' in the constraints:
Show a'
arising from a use of assertEqual' at List_Test.hs:6:27-58
Eq a' arising from a use of `assertEqual' at List_Test.hs:6:27-58
Probable fix: add a type signature that fixes these type variable(s)

List_Test.hs:

module List_Test
where
import List
import Test.HUnit

fromEmptyList = TestCase $ assertEqual "" [] (toList (Nil))

main = runTestTT fromEmptyList

List.hs:

module List
where
data List a = Cons a (List a)
            | Nil
              deriving (Show)

toList Nil = []
toList (Cons a b) = (:) a (toList b) 

I've tried adding type constraints to both the List declaration and the toList definition without success. A internet search did also not provide any information.

Best Answer

The issue is partially that GHC does not know that toList Nil will return an empty list.

*List> :i toList
toList :: List a -> [a]     -- Defined at List.hs:7:0-5

It only knows that it will return a list of type a, but it has no idea what a is -- hence the "ambiguous type variable a" message. One way to work around this is to just specify the type of list that toList will return:

fromEmptyList = TestCase $ assertEqual "" [] (toList (Nil) :: [Int])

Changing that, and removing the first two lines of List_Test (it will not look for a main function in a named module that is not named Main), gave me this result:

$ runghc List_Test.hs 
Cases: 1  Tried: 1  Errors: 0  Failures: 0
Related Topic