Search code examples
haskelltypestype-mismatch

Change variable type to match the expected type


In the following code, I get the error

Couldn't match type 'Integer' with 'Int'
Expected type :[(Test, [Test])]
Actual type : [(Integer, [Integer])]

when executing

testFunc test

with the following declaration

type TestType = Int
a = [(1,[2,3])]

testFunc :: [(TestType ,[TestType])] -> TestType 
testFunc ((a,(b:c)):d) = a

How do I declare my list a so that it matches the type of testFunc?

And is there a way to fix the error without modifying type Test = Int or the declaration of a?


Solution

  • How do I declare my list 'test' so that it matches the type of testFunc?

    Well, by declaring this as the type.

    a :: [(TestType, [TestType])]
    a = [(1,[2,3])]
    

    Generally speaking, you should always give explicit type signatures for top-level definitions like this. Without such a signature, the compiler will pick one for you. Generally Haskell tries to pick the most general available type possible; in this case that would be

    a :: (Num a, Num b) => [(a, [b])]
    

    ...which would include both [(Int, [Int])] and [(Integer, [Integer])]. However, the monomorphism restriction restricts the type by default, excluding such polymorphism. So GHC has to pick one version, and the default one is Integer, not Int.

    The right solution, again, is to provide an explicit signature. However, you can also turn off the monomorphism restriction:

    {-# LANGUAGE NoMonomorphismRestriction #-}
    
    type TestType = Int
    a = [(1,[2,3])]
    
    testFunc :: [(TestType ,[TestType])] -> TestType 
    testFunc ((x,(y:z)):w) = x
    
    main :: IO ()
    main = print $ testFunc a