2012-10-12 71 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

非常感謝您的幫助和答覆。 –