为什么 Haskell (Hugs) 中的 Show 实例会导致堆栈溢出错误?

发布于 2024-12-11 12:59:31 字数 744 浏览 1 评论 0原文

下面是 Haskell 中的多态数据类型,由 Hugs 解释。我正在尝试创建一个 Show for Equality 的实例。

实例声明表示,如果类型“a”在 Show 中,则相等 a 在 Show 中。它应该以“a = b”的形式将两个参数打印到构造函数 Equals ab。

data Equality a = Equals a a 

instance (Show a) => Show (Equality a) where
show (Equals a b) = a ++ " = " ++ b

然而,在 Hugs 中输入诸如“(Equality 9 9)”之类的内容会产生:

ERROR - C stack Overflow

因此,我尝试将“show (Equals ab)...”行缩进几个空格。我不确定有什么区别,但只是玩了一下,然后得到了这个:

Inferred type is not general enough
*** Expression    : show
*** Expected type : Show (Equality a) => Equality a -> String
*** Inferred type : Show (Equality [Char]) => Equality [Char] -> String

任何人都可以解释为什么会发生这些错误,或者建议一种更好的方法来实现这个显示实例?

谢谢你!

The following is a polymorphic data type in Haskell, interpreted by Hugs. I am trying to create an instance of Show for Equality.

The instance declaration says that if a type "a" is in Show, then Equality a is in Show. It should print the two arguments to the constructor Equals a b in the form "a = b".

data Equality a = Equals a a 

instance (Show a) => Show (Equality a) where
show (Equals a b) = a ++ " = " ++ b

Yet, typing something into Hugs like "(Equality 9 9)" yields:

ERROR - C stack overflow

So, I tried indenting the "show (Equals a b)..." line with a couple of spaces. I'm not sure what the difference would be, but was just playing around and then got this:

Inferred type is not general enough
*** Expression    : show
*** Expected type : Show (Equality a) => Equality a -> String
*** Inferred type : Show (Equality [Char]) => Equality [Char] -> String

Can anyone explain why these errors are occurring, or suggest a better way of implementing this show instance?

Thank you!

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

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

发布评论

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

评论(3

苍风燃霜 2024-12-18 12:59:31

您的代码缩进不正确。它定义了一个空的 Show 实例:

instance (Show a) => Show (Equality a) where

和一个单独的顶级函数 show:

show (Equals a b) = a ++ " = " ++ b

类型为 Equality [Char] -> [字符]。因此,当您尝试使用 Show 实例时,Show 获取 show 的默认定义。查看代码:

showsPrec _ x s = show x ++ s
show x          = showsPrec zeroInt x ""

您可以看到默认的 show 是根据 showsPrec 定义的,而 showsPrec 又是根据 show 定义的。这解释了为什么你的程序会进入无限循环。

要修复代码,请适当缩进它,并添加对 show 的缺失调用来修复类型错误(这是由于您无法连接任意类型 a使用字符串 - 您必须首先将 a 转换为字符串):

data Equality a = Equals a a

instance (Show a) => Show (Equality a) where
  show (Equals a b) = show a ++ " = " ++ show b

测试:

*Main> show (Equals 9 9)
"9 = 9"

Your code is indented incorrectly. It defines an empty Show instance:

instance (Show a) => Show (Equality a) where

and a separate top-level function show:

show (Equals a b) = a ++ " = " ++ b

of type Equality [Char] -> [Char]. So when you try to use your Show instance, the default definition of show from the Show class gets picked up. Looking at the code:

showsPrec _ x s = show x ++ s
show x          = showsPrec zeroInt x ""

you can see that the default show is defined in terms of showsPrec, which is in turn defined in terms of show. This explains why your program goes into an infinite loop.

To fix the code, indent it appropriately, and add missing calls to show to fix the type error (which stems from the fact that you can't concatenate an arbitrary type a with a string - you have to convert a to a string first):

data Equality a = Equals a a

instance (Show a) => Show (Equality a) where
  show (Equals a b) = show a ++ " = " ++ show b

Testing:

*Main> show (Equals 9 9)
"9 = 9"
戴着白色围巾的女孩 2024-12-18 12:59:31

由于 Haskell 有时对空白的敏感性很奇怪,缩进确实很重要。如果没有缩进,编译器无法判断以下语句属于 where

您收到的错误是因为没有约束的多态类型不能确保 ab 可以与“=”字符串连接。如果您有 Equals 1 1 该怎么办?如果不首先创建 Ints 字符串,您将如何连接它?

但是,如果您首先 show a 和 b,那么一切都会成功,因为 show 会将这些值转换为可以与字符串连接的内容。

data Equality a = Equals a a

instance (Show a) => Show (Equality a) where
    show (Equals a b) = (show a) ++ " = " ++ (show b)

The indenting does matter due to Haskell's at-times-strange whitespace sensitivity. Without the indent, the compiler cannot tell that the following statement belongs to the where.

The error that you are getting is because the polymorphic type, having no constraints, does not ensure that a and b can concatenated with the " = " string. What if you have Equals 1 1. How would you concatenate that without making the Ints strings first?

However, if you show a and b first, all works out because show martials the values into something that can be concatenated with a String.

data Equality a = Equals a a

instance (Show a) => Show (Equality a) where
    show (Equals a b) = (show a) ++ " = " ++ (show b)
归属感 2024-12-18 12:59:31

我认为你的问题是你没有在参数 ab 上调用函数 show 。我在 GHC 中做了这个,但我认为它应该有效:

data Equality a = Equals a a 

instance (Show a) => Show (Equality a) where
  show (Equals a b) = show a ++ " = " ++ show b

然后:

> Equals 9 9
9 = 9

I think your problem is that you didn't call function show on arguments a and b. I did this in GHC but I think it should work:

data Equality a = Equals a a 

instance (Show a) => Show (Equality a) where
  show (Equals a b) = show a ++ " = " ++ show b

Then:

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