2012-01-25 64 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,因此只有IO a類型的表達式纔會出現在該do-block中。但是,你得到的有些奇怪的錯誤消息,因爲功能的應用程序的優先級最高,因此上述行被解析

(createVectorTuple (words appData)) : vector1 

這是[(String, Float)]類型的表達式(如果vector1有型)。現在[]也是一個monad,因此[a]類型的表達式可以出現在do-blocks中,但是該塊中的所有表達式都必須具有列表類型。但

 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

你也必須在return之後的東西putStrLn「就是這樣。」所以if的兩個分支都具有相同的類型。例如:

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