Haskell类型在do块中不匹配

时间:2016-04-26 13:21:55

标签: haskell types io type-mismatch

在学习Haskell"以获得更大的利益时#34; (又称通过功能语言考试), 我遇到了一个奇怪的错误。我在每个do-block中都会遇到Type不匹配错误(第一个除外)。为了更准确,编译器似乎期待一个列表。

我认为它与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
}

1 个答案:

答案 0 :(得分: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