我正在尝试编写一个加载2个文本文件的程序,将这些文件中的数字转换为2个列表,然后计算这些列表之间的皮尔逊相关性。
pearson函数只能使用浮点数,所以我创建了一个名为floatconvert的函数来尝试解决这个问题,但事实并非如此。我收到错误消息“无法将预期类型'IO b0'与实际类型'Float匹配'。在'皮尔逊'的第一个参数中,即'input1'。“
非常感谢您解决此问题的任何帮助。
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 ])
答案 0 :(得分:10)
在这种情况下,错误消息有些误导。真正的问题是pearson
不会返回IO something
。如果您打算打印结果,请写
main = do
...
print $ pearson input1 input2
这里GHC混淆的原因是皮尔逊的推断类型是
pearson :: Floating a => [a] -> [a] -> a
因此,当您尝试将其用作do-block中的语句时,它会从a ~ IO b
的返回类型推断,因此参数必须具有类型[IO b]
。但是,它已经知道它们具有类型[Float]
,因此当问题的根源是返回时,您会收到一条令人困惑的错误消息,指出它无法在参数中将Float
与IO b
匹配类型。
我是第二个Dave关于在函数中添加类型签名的建议。它可以使错误消息更有帮助。例如,如果您提供了pearson
类型签名pearson :: [Float] -> [Float] -> Float
,您就会收到此消息:
Pearson.hs:8:5:
Couldn't match expected type `IO b0' with actual type `Float'
In the return type of a call of `pearson'
In a stmt of a 'do' block: pearson input1 input2