如何解决这些Haskell Kind错误

时间:2011-05-25 21:05:51

标签: haskell types

所以我一直在搞乱Haskell,我在代码中遇到了这个奇怪的错误。

“'IO'不适用于足够的类型参数
   期待的'?',但'IO'有点' - > '
   在'loop'的类型签名中:loop :: State - > IO“

以下是代码

import System.IO
data State = State [Int] Int Int deriving (Show)

main = do
   loop (State [] 0 0)

loop::State -> IO
loop state = do
   putStr "file: "
   f <- getLine
   handle <- openFile f ReadMode
   cde <- hGetContents handle
   hClose handle
   putStrLn cde
   loop state

如何修复此错误?此外,任何有关种类的见解将不胜感激。

3 个答案:

答案 0 :(得分:11)

IOtype constructor,不是完整类型。你应该声明

loop :: State -> IO ()

其中()单位类型;只有一个值的类型,拼写为()。这是永久循环或任何其他不返回(有意义)值的函数的适当类型。

答案 1 :(得分:11)

IO是一个类型的构造函数,这意味着它需要一个参数才能成为一个类型。所以:

IO Int
IO String
IO ()

是类型,但IO本身不是。

IO种类* -> *,就像说它是一个接受类型并返回类型的函数。

我建议改变

loop :: State -> IO

loop :: State -> IO ()

()是“单位类型”,它只有一个值(也称为()),通常用于{C}类语言中使用void的地方)

答案 2 :(得分:4)

正如其他人所提到的,IO是一个类型构造函数,而不是一个类型。所以你必须将它应用于其他类型。类型IO Foo的值意味着它是一个可能执行某些I / O然后返回类型Foo的值的计算。

luqui和larsman建议您使用()作为返回值。我认为以下类型是永远循环的函数的更好选择:

loop :: String -> IO a

请注意,该函数现在在返回值中是多态的。这种类型比返回()提供更多信息。为什么?因为此类型的函数必须是循环函数。无法使用此类型实现终止功能。该函数的用户将立即从该类型中看到它是一个循环函数。所以你可以免费获得这种类型的文档。