不能使用 Show,即使类型实现了它

Can not use Show even if type implements it

我不明白为什么我 Show typeclass 抱怨使用自定义类型,因为我已经为它提供了一个实例:

自定义类型

data Numeric=I Int | D Double 

instance Show Numeric where
        show (I x)=show x
        show (D y)=show y

 instance Num Numeric where
        (+) (I a) (I b) =I (a+b)
        (+) (D a) (I b) =D (a+ fromIntegral b)
        (+) (I a) (D b)=D (fromIntegral a+b)
        (-) (D a) (I b)= D (a- fromIntegral b)
        (-) (I a) (D b)=D(fromIntegral a -b)

抱怨的方法

arrayToString::Num a=>[a]->String
arrayToString arr =intercalate "," $ map show arr

所以考虑到我的 type 实现了 NumShow 类型类,我不明白为什么当我给 arrayToString a [Numeric]价值

错误

* Could not deduce (Show a) arising from a use of `show'
      from the context: Num a
        bound by the type signature for:
                   arrayToString :: forall a. Num a => [a] -> String
        at Types.hs:40:5-37
      Possible fix:
        add (Show a) to the context of
          the type signature for:
            arrayToString :: forall a. Num a => [a] -> Strin

如果你想展示一些东西然后使用Show约束:

arrayToString :: (Show a) => [a] -> String

i do not understand why it has renders this error when i am feeding arrayToString a [Numeric] value

请注意函数 arrayToString 没有任何特定于 NumNumeric 的内容。它所做的只是为任何可显示的内容呈现一个字符串(通过 show)。

问题是您没有使用您的自定义类型。

给定的类型签名是 arrayToString :: forall a. Num a => [a] -> String。您已经对属于 Num 类型 class 的所有可能类型 a 进行了普遍量化。此 包括 您的类型,但也包括所有其他已存在且将永远存在的数字类型。这个说法太大胆了。

您可能需要考虑将签名更改为 arrayToList :: [Numeric] -> String,直接使用您的类型,而不是依赖参数多态性。

此外,作为旁注,[] 是单向链表(或缺点列表),而不是数组。

编辑:要将这个问题转化为逻辑,你所做的就是说

  • 有一组东西叫做Numeric
  • Numeric 的元素是 class 元素 NumShow
  • 的成员
  • 因此,对于 Num class 中的 每个可能的类型 ,我可以将该类型的列表转换为字符串

你已经大大增加了声明的范围,以至于它包含了一大堆我们一无所知的类型,也没有证据表明它们可以变成字符串。