所以我一直在搞乱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
如何修复此错误?此外,任何有关种类的见解将不胜感激。
答案 0 :(得分:11)
IO
是type 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
请注意,该函数现在在返回值中是多态的。这种类型比返回()
提供更多信息。为什么?因为此类型的函数必须是循环函数。无法使用此类型实现终止功能。该函数的用户将立即从该类型中看到它是一个循环函数。所以你可以免费获得这种类型的文档。