2016-04-26 99 views
0

在學習Haskell「爲更好的」(又名通過功能語言考試), 我遇到了一個奇怪的錯誤。每個do-block中都會出現類型不匹配錯誤(第一個除外)。爲了更準確,編譯器似乎期望一些東西。Haskell類型不匹配在塊

我覺得它有什麼做的IO操作...

代碼:

-- chaos.hs 
import System.IO 

main :: IO() 
main = do           -- no error 
     inl <- openFile "dictionary.txt" ReadMode 
     let lang = extractLang (inl) 
     hClose inl 

extractLang :: Handle -> String 
extractLang file = do        --error 
        eof <- hIsEOF file 
        if eof 
         then do hClose file   --error 
           "none" 
         else do line <- hGetLine file --error 
           if length (words line) == 1 
           then line 
           else extractLang file 

錯誤日誌:

chaos.hs:12:27: 
Couldn't match type ‘IO’ with ‘[]’ 
Expected type: [Bool] 
    Actual type: IO Bool 
In a stmt of a 'do' block: eof <- hIsEOF file 
In the expression: 
    do { eof <- hIsEOF file; 
     if eof then 
      do { hClose file; 
       .... } 
     else 
      do { line <- hGetLine file; 
       .... } } 

chaos.hs:14:31: 
    Couldn't match type ‘IO’ with ‘[]’ 
    Expected type: [()] 
     Actual type: IO() 
    In a stmt of a 'do' block: hClose file 
    In the expression: 
     do { hClose file; 
      "none" } 

chaos.hs:16:39: 
    Couldn't match type ‘IO’ with ‘[]’ 
    Expected type: [String] 
     Actual type: IO String 
     In a stmt of a 'do' block: line <- hGetLine file 
     In the expression: 
     do { line <- hGetLine file; 
      if length (words line) == 1 then line else extractLang file 
} 

回答

4

你是完全正確的,因爲它具有與IO操作有關。首先,extractLang的正確類型是Handle -> IO String。其次,幾個return s丟失(出於同樣的原因):

extractLang :: Handle -> IO String 
extractLang file = do         
        eof <- hIsEOF file 
        if eof 
         then do hClose file    
           return "none"   -- return 
         else do line <- hGetLine file 
           if length (words line) == 1 
           then return line  -- return 
           else extractLang file