即使类型实现也不能使用Show

时间:2018-12-31 13:50:55

标签: haskell typeclass

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

自定义类型

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[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

2 个答案:

答案 0 :(得分:7)

如果要显示某些内容,请使用Show约束:

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

当我向arrayToString提供[Numeric]值时,我不明白为什么会出现此错误

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

答案 1 :(得分:7)

问题是您不是使用自定义类型。

给定的类型签名为arrayToString :: forall a. Num a => [a] -> String。您已经对a类型类的所有可能类型Num进行了量化。这包括您的类型,但也包括所有将要存在的其他数字类型。这句话太大胆了。

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

此外,[]是单链接列表(或约束列表),而不是数组。

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

  • 有一整套称为Numeric
  • Numeric的元素是类NumShow的成员
  • 因此,对于Num类中的所有可能的类型,我可以将该类型的列表转换为字符串

您已经大大增加了该语句的范围,以使其包含一堆我们一无所知的类型,并且没有证据证明它们可以转换为字符串。