2012-10-12 46 views
3

我试图编写一个加载2个文本文件的程序,将这些文件中的数字转换为2个列表,然后计算这些列表之间的皮尔逊校正。Pearson与Haskell浮点类型冲突的相关

皮尔逊函数只能使用浮点数,所以我做了一个名为floatconvert的函数来试图解决这个问题,但它没有。我收到一个错误,说“无法匹配预期类型'IO b0'与实际类型'浮动'。在'皮尔森'的第一个参数,即'输入1'。“

任何帮助解决这个问题将不胜感激。

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

添加型签名的功能,并且错误信息将得到更接近,其中的错误是。 – dave4420

回答

10

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

main = do 
    ...  
    print $ pearson input1 input2 

原因GHC的困惑这里是推断出的类型皮尔森是

pearson :: Floating a => [a] -> [a] -> a 

所以当您尝试使用它作为在做一个声明-block,它从返回类型推断出a ~ IO b,因此参数必须具有类型[IO b]。但是,它已知道它们的类型为[Float],所以当问题的源是返回类型时,您会收到一条令人困惑的错误消息,说明它无法在参数中匹配FloatIO b

我第二次戴夫关于添加类型签名到你的函数的建议。它可以使错误消息更有帮助。例如,如果你给了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 
+0

非常感谢您的帮助和答复。 –