3

2 つのテキスト ファイルを読み込み、それらのファイルの数値を 2 つのリストに変換し、それらのリスト間のピアソン相関を計算するプログラムを作成しようとしています。

pearson 関数は float しか使用できないため、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 ])
4

1 に答える 1

10

この場合、エラー メッセージは誤解を招く可能性があります。本当の問題は、pearsonが返されないことIO somethingです。結果を印刷するつもりだった場合は、次のように記述します

main = do
    ...    
    print $ pearson input1 input2

ここで GHC が混乱する理由は、推論されるピアソンの型が

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

したがって、do ブロック内のステートメントとして使用しようとすると、戻り値の型から推測されるa ~ IO bため、引数には type が必要[IO b]です。ただし、型があることは既に認識されているため、問題の原因が戻り値の型である場合、引数で一致[Float]できないという紛らわしいエラー メッセージが表示されます。FloatIO b

関数に型シグネチャを追加することについての Dave のアドバイスに賛成です。エラーメッセージをより役立つものにすることができます。たとえばpearson、型 signatureを指定した場合、次の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
于 2012-10-12T16:15:38.203 に答える