即使type实现它也不能使用Show

Ber*_*ian 3 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)
Run Code Online (Sandbox Code Playgroud)

抱怨的方法

arrayToString::Num a=>[a]->String
arrayToString arr =intercalate "," $ map show arr
Run Code Online (Sandbox Code Playgroud)

因此,鉴于我的type实现Num和Show类型类,我不明白为什么它在我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
Run Code Online (Sandbox Code Playgroud)

sar*_*ara 8

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

给定的类型签名是arrayToString :: forall a. Num a => [a] -> String.您已经a对作为Num类型类成员的所有可能类型进行了普遍量化.这包括您的类型,但也包括存在且永远存在的所有其他数字类型.这是一个过于大胆的声明.

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

另外,作为旁注,[]是单个链表(或缺点列表),而不是数组.

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

  • 有一套叫做的东西 Numeric
  • 元素Numeric是类Num和的成员Show
  • 因此,对于每一个可能的类型永远是在Num类,我可以把这种类型的列表转换为字符串

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

  • @Redu*"......作为Num类型类实例的所有已知数据类型也是Show类类的实例......"*这通常不正确,例如可以实现`(Num b)= > Num(a - > b)`实例.Haskell拒绝推断所有'Num`s'都是`Show`s,因为后来可能不会这样. (2认同)
  • @Redu如果这是一个可以由其他人定义的库导入的GHC,那么GHC在创建库时就不知道了,那么呢? (2认同)

Tho*_*son 7

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

arrayToString :: (Show a) => [a] -> String
Run Code Online (Sandbox Code Playgroud)

我不明白为什么当我给arrayToString一个[Numeric]值时它会出现这个错误

请注意,该功能arrayToString没有特定于Num或的任何内容Numeric.它所做的就是为Showable(via show)渲染一个字符串.

  • 你的函数`arrayToString`与你的类型`Numeric`没有任何关系,它只是一个以特殊方式呈现`Show`able值的函数.它无法呈现不可显示的值,而"Num"与其操作无关. (6认同)