皮尔逊与哈斯克尔浮点型冲突的相关性



>我正在尝试编写一个程序来加载 2 个文本文件,将这些文件中的数字转换为 2 个列表,然后计算这些列表之间的 pearson 相关性。

pearson 函数只能接受浮点数,所以我做了一个名为 floatconvert 的函数来尝试解决这个问题,但它没有。我收到一条错误消息,指出"无法将预期类型'IO b0'与实际类型'浮点型'匹配。在'皮尔逊'的第一个论点中,即'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 ])

在这种情况下,错误消息有些误导。真正的问题是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

最新更新