以下是Haskell中的多态数据类型,由Hugs解释。我正在尝试创建一个"平等显示"的实例。
实例声明指出,如果类型"a"在"显示"中,则相等 a 在"显示"中。它应该将两个参数打印到构造函数 Equals a b,形式为"a = b"。
data Equality a = Equals a a
instance (Show a) => Show (Equality a) where
show (Equals a b) = a ++ " = " ++ b
然而,在拥抱中输入诸如"(平等 9 9("之类的内容会产生:
错误 - C 堆栈溢出
所以,我尝试缩进"显示(等于 b(..."与几个空格一起行。我不确定会有什么区别,但只是在玩,然后得到了这个:
Inferred type is not general enough
*** Expression : show
*** Expected type : Show (Equality a) => Equality a -> String
*** Inferred type : Show (Equality [Char]) => Equality [Char] -> String
谁能解释为什么会发生这些错误,或者建议实现此 show 实例的更好方法?
谢谢!
您的代码缩进不正确。它定义了一个空的Show
实例:
instance (Show a) => Show (Equality a) where
以及一个单独的顶级函数show
:
show (Equals a b) = a ++ " = " ++ b
类型 Equality [Char] -> [Char]
.因此,当您尝试使用 Show
实例时,将选取 Show
类中 show
的默认定义。查看代码:
showsPrec _ x s = show x ++ s
show x = showsPrec zeroInt x ""
您可以看到默认show
是根据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"
Haskell 有时奇怪的空格敏感性,缩进确实很重要。如果没有缩进,编译器无法分辨以下语句属于where
。
您得到的错误是因为多态类型没有约束,不能确保a
和b
可以与" = "字符串连接。如果你有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)
我认为您的问题是您没有在参数a
和b
上调用函数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