Rnet
Rnet

Reputation: 5040

How are types determined?

I've written some xyz program, and prints something on the screen, very irrelevant. In this code I'm finding that if I remove a line which is not related to what I want to print I'm getting an error.

import Data.Array

horizontal inArray limit listLen = [ findProd i j | i<-[1..limit], j<-[1..(limit - listLen)]]
            where 
            findProd a b = product [ inArray!(a,b+k) | k<-[0..(listLen-1)] ]

vertical inArray limit listLen = [ findProd i j | i<-[1..(limit-listLen)], j<-[1..limit]]
            where 
            findProd a b = product [ inArray!(a+k,b) | k<-[0..(listLen-1)] ]

rightDiag inArray limit listLen = [ findProd i j | i<-[1..(limit - listLen)], j<-[1..(limit - listLen)] ]
            where
            findProd a b = product [ inArray!(a+k,b+k) | k<-[0..(listLen-1)] ]

leftDiag inArray limit listLen= [ findProd i j | i <-[1..(limit - listLen)],j<-[listLen..limit] ]
            where
            findProd a b = product [ inArray!(a+k,b-k) | k<-[0..(listLen-1)] ]

solve = do
        x <- readFile "matrix.txt"              
        let limit = 20
        let listLen = 4
        let inArray = listArray ((1,1),(limit,limit)) $ ( map read (words x))
        let maxprod = maximum $ map maximum $ map (\f -> f inArray limit listLen) [horizontal,vertical,rightDiag,leftDiag]
        print inArray

Here if I remove the line

let maxprod = maximum $ map maximum $ map (\f -> f inArray limit listLen) [horizontal,vertical,rightDiag,leftDiag]

I'm getting a compilation error. How? it is not even related to what I want to print.

Upvotes: 0

Views: 121

Answers (1)

Jeff Foster
Jeff Foster

Reputation: 44706

The error message you are getting is:

Ambiguous type variable `a' in the constraints:
  (Read a) arising from a use of `read' at Temp.hs:23:63-66
  (Show a) arising from a use of `print' at Temp.hs:25:9-13
Probable fix: add a type signature that fixes these type variable(s)

Because you've used print the compiler has decided that inarray is an instance of Show. Removing the print means it has no way of determining that.

Adding explicit type declarations will help as the type of read is read :: Read a => String -> a (e.g. it can return anything) and the compiler has no way of nowing this is an instance of Show. I assume you are reading some kind of number as the file is called matrix.txt? You could try something like this.

let readInt = read :: String -> Integer
let inArray = listArray ((1,1),(limit,limit)) $ (map readInt (words x))

And now the compiler knows that inArray is an array of integers and is thus showable.

Upvotes: 5

Related Questions