I’m trying to write a program that loads 2 text files, converts the numbers in those files into 2 lists, and then calculates the pearson correletion between those lists.
The pearson function can only take floats, so I made a function called floatconvert to try to fix this problem, but it hasn’t. I get an error saying “Couldn’t match expected type ‘IO b0’ with actual type ‘Float.’ In the first argument of ‘pearson’, namely ‘input1.'”
Any help with fixing this problem would be greatly appreciated.
main = do
input1file <- readFile "input1.txt"
input2file <- readFile "input2.txt"
let input1 = floatconvert input1file
let input2 = floatconvert input2file
pearson input1 input2
floatconvert x = [ read a::Float | a <- words x ]
pearson xs ys = (psum-(sumX*sumY/n))/(sqrt((sumXsq-(sumX**2/n)) * (sumYsq-(sumY**2/n))))
where
n = fromIntegral (length xs)
sumX = sum xs
sumY = sum ys
sumXsq = sum([ valX*valX | valX <- xs ])
sumYsq = sum([ valY*valY | valY <- ys ])
psum = sum([ fst val * snd val | val <- zip xs ys ])
The error message is somewhat misleading in this case. The real problem is that
pearsondoes not returnIO something. If you meant to print the result, writeThe reason for GHC’s confusion here is that the inferred type of pearson is
so when you try to use it as a statement in the do-block, it infers from the return type that
a ~ IO band therefore the arguments must have type[IO b]. However, it already knows that they have type[Float]so you get a confusing error message about it being unable to matchFloatwithIO bin the argument when the source of the problem is the return type.I second Dave’s advice about adding type signatures to your functions. It can make error messages more helpful. For example, if you had given
pearsonthe type signaturepearson :: [Float] -> [Float] -> Float, you would have gotten this message: