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

sub*_*ray 3 algorithm haskell type-conversion

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

pearson函数只能使用浮点数,所以我创建了一个名为floatconvert的函数来尝试解决这个问题,但事实并非如此.我收到错误消息"无法将预期类型'IO b0'与实际类型'Float匹配'.在'pearson'的第一个参数中,即'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 ])
Run Code Online (Sandbox Code Playgroud)

ham*_*mar 10

在这种情况下,错误消息有些误导.真正的问题是pearson不返回IO something.如果您打算打印结果,请写

main = do
    ...    
    print $ pearson input1 input2
Run Code Online (Sandbox Code Playgroud)

这里GHC混淆的原因是皮尔逊的推断类型是

pearson :: Floating a => [a] -> [a] -> a
Run Code Online (Sandbox Code Playgroud)

因此,当您尝试将其用作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
Run Code Online (Sandbox Code Playgroud)