3

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

实例声明说如果类型“a”在 Show 中,那么 Equality 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)”之类的内容会产生:

错误 - C 堆栈溢出

所以,我尝试用几个空格缩进“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

谁能解释为什么会发生这些错误,或者提出更好的方法来实现这个展示实例?

谢谢!

4

3 回答 3

3

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

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

和一个单独的顶级函数show

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

的类型Equality [Char] -> [Char]。因此,当您尝试使用您的Show实例时,将从中获取默认定义。showShow看代码:

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"
于 2011-10-22T23:55:29.810 回答
1

我认为您的问题是您没有show在参数ab. 我在 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
于 2011-10-22T23:44:41.207 回答
1

由于 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)
于 2011-10-22T23:45:33.390 回答