为什么 Haskell (Hugs) 中的 Show 实例会导致堆栈溢出错误?
下面是 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的代码缩进不正确。它定义了一个空的
Show
实例:和一个单独的顶级函数
show
:类型为
Equality [Char] -> [字符]
。因此,当您尝试使用Show
实例时,从Show
类 获取show
的默认定义。查看代码:您可以看到默认的
show
是根据showsPrec
定义的,而showsPrec
又是根据show
定义的。这解释了为什么你的程序会进入无限循环。要修复代码,请适当缩进它,并添加对
show
的缺失调用来修复类型错误(这是由于您无法连接任意类型a
使用字符串 - 您必须首先将a
转换为字符串):测试:
Your code is indented incorrectly. It defines an empty
Show
instance:and a separate top-level function
show
:of type
Equality [Char] -> [Char]
. So when you try to use yourShow
instance, the default definition ofshow
from theShow
class gets picked up. Looking at the code:you can see that the default
show
is defined in terms ofshowsPrec
, which is in turn defined in terms ofshow
. 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 typea
with a string - you have to converta
to a string first):Testing:
由于 Haskell 有时对空白的敏感性很奇怪,缩进确实很重要。如果没有缩进,编译器无法判断以下语句属于
where
。您收到的错误是因为没有约束的多态类型不能确保
a
和b
可以与“=”字符串连接。如果您有Equals 1 1
该怎么办?如果不首先创建 Ints 字符串,您将如何连接它?但是,如果您首先
show
a 和 b,那么一切都会成功,因为show
会将这些值转换为可以与字符串连接的内容。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
andb
can concatenated with the " = " string. What if you haveEquals 1 1
. How would you concatenate that without making the Ints strings first?However, if you
show
a and b first, all works out becauseshow
martials the values into something that can be concatenated with a String.我认为你的问题是你没有在参数
a
和b
上调用函数show
。我在 GHC 中做了这个,但我认为它应该有效:然后:
I think your problem is that you didn't call function
show
on argumentsa
andb
. I did this in GHC but I think it should work:Then: