Can not use Show even if type implements it

Viewed 111

I do not understand why i Show typeclass complains on using a custom type since i already provided an instance for it :

Custom Type

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)

Method that complains

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

So given my type that implements Num and Show typeclasses i do not understand why it has renders this error when i am feeding arrayToString a [Numeric] value

Error

* 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 Answers

The problem is that you are not using your custom type.

The given type signature is arrayToString :: forall a. Num a => [a] -> String. You have universally quantified over all possible types a that are members of the Num typeclass. This includes your type but also every other numeric type that exists and ever will exist. This is too bold a statement.

You might want to consider changing the signature to arrayToList :: [Numeric] -> String, using your type directly, instead of relying on parametric polymorphism.

Also, as a side-note, [] is a singly linked list (or a cons-list), not an array.

EDIT: To translate this issue into logic, what you have done is to say

  • There is a set of things called Numeric
  • Elements of Numeric are members of the classes Num and Show
  • Therefore, for every possible type ever that is in the Num class, I can turn a list of that type into a string

You have drastically increased the scope of the statement so that it includes a whole bunch of types we know nothing about and have no proof that they can be turned into strings.

If you want to show something then use the Show constraint:

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

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

Notice the function arrayToString doesn't have anything specific to Num or Numeric. All it does is render a string for anything Showable (via show).

Related