如何解决这些 Haskell 类型错误

发布于 2024-11-09 14:21:14 字数 539 浏览 0 评论 0原文

所以我一直在摆弄 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

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

So I've been messing around with Haskell, and I've come across this strange error in my code.

" 'IO' is not applied to enough type arguments
Expected kind '?', but 'IO' has kind '->'
In the type signature for 'loop': loop :: State -> IO"

Here is the Code

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

How do I fix this error? Also, any insight on kinds would be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

開玄 2024-11-16 14:21:14

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

IO Int
IO String
IO ()

是类型,但 IO 本身不是类型。

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

我建议更改

loop :: State -> IO

loop :: State -> IO ()

(() 是“单位类型”,它只有一个值(也称为 ()),通常在 void 的情况下使用 将用于类 C 语言)

IO is a type constructor, which means that it needs an argument in order to become a type. So:

IO Int
IO String
IO ()

are types, but IO by itself is not.

The kind of IO is * -> *, which is like saying it is a function that takes a type and returns a type.

I would suggest changing

loop :: State -> IO

to

loop :: State -> IO ()

(() is the "unit type", it has only one value (also called ()), and is typically used where void would be used in C-like languages)

め七分饶幸 2024-11-16 14:21:14

IO 是一个 类型构造函数,而不是完整类型。您应该声明

loop :: State -> IO ()

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

IO is a type constructor, not a full type. You should declare

loop :: State -> IO ()

where () is the unit type; the type with only one value, also spelled (). That's the appropriate type for an eternal loop or any other function that does not return a (meaningful) value.

吃颗糖壮壮胆 2024-11-16 14:21:14

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

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

loop :: String -> IO a

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

As others have mentioned, IO is a type constructor, not a type. So you have to apply it to some other type. A value of type IO Foo means that it is a computation which potentially does some I/O and then returns a value of type Foo.

luqui and larsman suggested that you should use () as a return value. I think the following type is a better alternative for a function that loops forever:

loop :: String -> IO a

Note that the function now is polymorphic in the return value. This type is much more informative than having it return (). Why? Because a function of this type must be a looping function. There is no way to implement a terminating function with this type. A user of this function will see immediately from the type that it is a looping function. So you get some documentation for free with this type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文