2012-01-25 23 views
3

フォーム "a 2"のユーザー入力を読み込んでタプルに変換し、それをタプルのリストに追加する関数を開発しています。これは、ユーザーが「完了」を入力するまで起き続けると考えられています。次のようにHaskell IO関数 - >型マッチエラー

コードは、このファイルを実行しようとすると...

getVectorData vector1 = do 
       putStrLn "Enter dimension and coefficient separated by a space: Enter \"Done\" to move on to next vector: " 
       appData <- getLine 

       if appData == "done" then 
        putStrLn "That's it" 
       else do 
        createVectorTuple (words appData) : vector1 
        getVectorData vector1 

createVectorTuple :: [String] -> (String, Float) 
createVectorTuple vectorData = ((head vectorData) , (read (last vectorData) :: Float)) 

はどのようにこれまで、私は

> ERROR file:.\MainApp.hs:13 - Type error in final generator 
*** Term   : getVectorData vector1 
*** Type   : IO() 
*** Does not match : [a] 

は私が間違って何をやっているエラーが出ますか?

+0

ただし、createVectorTuple関数はうまくいきます。 –

答えて

4

IOと純粋な非IO機能を混在させています。

getVectorData vector1 = do 
    putStrLn "Enter dimension and coefficient separated by a space: Enter \"Done\" to move on to next vector: " 
    appData <- getLine 

    if appData == "done" then 
     putStrLn "That's it" 

上記全てIO

else do 
     createVectorTuple (words appData) : vector1 

createVectorTupleが非IO関数です。前の部分はIO do-blockなので、doブロックにはIO aという型の式しか出現しないことがあります。関数適用の優先順位が最も高いため、上記の行は、タイプ[(String, Float)]の表現である

(createVectorTuple (words appData)) : vector1 

を解析されるように、(vector1は、そのタイプを持っている場合)しかし、あなたは、やや奇妙なエラーメッセージが表示されます。今度は[]もモナドなので、タイプ[a]の式はdoブロックに現れることができますが、そのブロックのすべての式はリストタイプでなければなりません。しかし

 getVectorData vector1 

が上記部分から決定されたようなタイプIO()の発現があります。したがって、タイプは一致しません。確かに、報告された型の誤りは、その状況において可能な限り明確なものではない。あなたはおそらく

let vector2 = createVectorTuple (words appData) : vector1 
getVectorData vector2 

または完全に別の何かの線に沿って何かをしたい

、私は短いスニペットから伝えることはできません。

2

これはちょっと難しいですが、 "createVectorTupleは" IO() "型ではないので、おそらくこれは本当の問題です。" do "節はさまざまな型を持つことができるので、型推論はおそらく間違った推測では、「createVectorTuple」に基づいて、次の行は、その推測と一致しないため、エラーメッセージがあるあなたはおそらく言いたいことは

else 
    getVectorData $ createVectorTuple (words appData) : vector1 
0

が希望でしたです

:。

else do 
    let vector1 = createVectorTuple (words appData) 
    getVectorData vector1 
0

また、putStrLn「That's it」の後には、returnも必要です。したがって、ifの両方の枝は同じ型を持ちます。次のようなものがあります。

if appData == "done" then do 
     putStrLn "That's it" 
     return vector1 
    else getVectorData (createVectorTuple (words appData) : vector1)