Pearson与Haskell浮点型冲突的相关性

时间:2012-10-12 16:04:00

标签: algorithm haskell type-conversion

我正在尝试编写一个加载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 ])

1 个答案:

答案 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],因此当问题的根源是返回时,您会收到一条令人困惑的错误消息,指出它无法在参数中将FloatIO 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