Haskell: Couldn't match expected type ``Int' with actual type ``Integer'
One of the most frequent compilation error messages that I’ve been getting while working through the Project Euler problems in Haskell is the following:
Couldn't match expected type `Int' with actual type `Integer'
In problem 11, for example, I define the grid of numbers like so:
grid = [[08,02,22,97,38,15,00,40,00,75,04,05,07,78,52,12,50,77,91,08],
[49,49,99,40,17,81,18,57,60,87,17,40,98,43,69,48,04,56,62,00],
[81,49,31,73,55,79,14,29,93,71,40,67,53,88,30,03,49,13,36,65],
[52,70,95,23,04,60,11,42,69,24,68,56,01,32,56,71,37,02,36,91],
[22,31,16,71,51,67,63,89,41,92,36,54,22,40,40,28,66,33,13,80],
[24,47,32,60,99,03,45,02,44,75,33,53,78,36,84,20,35,17,12,50],
[32,98,81,28,64,23,67,10,26,38,40,67,59,54,70,66,18,38,64,70],
[67,26,20,68,02,62,12,20,95,63,94,39,63,08,40,91,66,49,94,21],
[24,55,58,05,66,73,99,26,97,17,78,78,96,83,14,88,34,89,63,72],
[21,36,23,09,75,00,76,44,20,45,35,14,00,61,33,97,34,31,33,95],
[78,17,53,28,22,75,31,67,15,94,03,80,04,62,16,14,09,53,56,92],
[16,39,05,42,96,35,31,47,55,58,88,24,00,17,54,24,36,29,85,57],
[86,56,00,48,35,71,89,07,05,44,44,37,44,60,21,58,51,54,17,58],
[19,80,81,68,05,94,47,69,28,73,92,13,86,52,17,77,04,89,55,40],
[04,52,08,83,97,35,99,16,07,97,57,32,16,26,26,79,33,27,98,66],
[88,36,68,87,57,62,20,72,03,46,33,67,46,55,12,32,63,93,53,69],
[04,42,16,73,38,25,39,11,24,94,72,18,08,46,29,32,40,62,76,36],
[20,69,36,41,72,30,23,88,34,62,99,69,82,67,59,85,74,04,36,16],
[20,73,35,29,78,31,90,01,74,31,49,71,48,86,81,16,23,57,05,54],
[01,70,54,71,83,51,54,69,16,92,33,48,61,43,52,01,89,19,67,48]]
Which has the following type:
> :t grid
grid :: [[Integer]]
The problem is that I wrote some functions to pass the grid to which expect it to be an array of array of Ints. For example the following function helps find the diagonals left to right from our current position:
-- implementation of findValue and hasItem isn't relevant here...
diagonalAt :: Int -> Int -> [[Int]] -> [Int]
diagonalAt x y grid = [findValue x y grid z | z <- [0..(length grid)],
hasItem grid (x + z),
hasItem (grid !! (x + z)) (y + z)]
> diagonalAt 0 0 grid
Couldn't match expected type `Int' with actual type `Integer'
Expected type: [[Int]]
Actual type: [[Integer]]
In the third argument of `diagonalAt', namely `x'
In the expression: diagonalAt 0 0 x
But if we give a type definition instead of allowing it to be inferred…
grid :: [[Int]]
-- definition of grid as before
…then it will be of the type we want:
> :t grid
grid :: [[Int]]
Alternatively we can make use of the http://www.haskell.org/haskellwiki/Converting_numbers function to convert from Integer to Int which in this situation leads to the following code:
> diagonalAt 0 0 (map (map fromIntegral) grid)
[8,49,31,23,51,3,67,20,97,45,3,24,44,52,26,32,40,4,5,48]
About the author
I'm currently working on short form content at ClickHouse. I publish short 5 minute videos showing how to solve data problems on YouTube @LearnDataWithMark. I previously worked on graph analytics at Neo4j, where I also co-authored the O'Reilly Graph Algorithms Book with Amy Hodler.