Why is Haskell interpreting my Num type as Enum?

I am trying to compile the following function in Haskell to simulate the differentiation of a polynomial whose constants are given in a numeric list:

diff :: (Num a) => [a] -> [a]
diff [] = error "Polynomial unspecified"
diff coeff = zipWith (*) (tail coeff) [0..]

      

Haskell refuses to compile it, giving me the following reason:

Could not deduce (Enum a) from the context (Num a)
 arising from the arithmetic sequence `0 .. ' at fp1.hs:7:38-42
Possible fix:
 add (Enum a) to the context of the type signature for `diff'
In the third argument of `zipWith', namely `[0 .. ]'
In the expression: zipWith (*) (tail coeff) ([0 .. ])
In the definition of `diff':
diff coeff = zipWith (*) (tail coeff) ([0 .. ])

      

Why [0..]

does Haskell treat a list as an Enum type and how can I fix it. Keep in mind that I want to use lazy evaluation here, hence an infinite list.

+2


source to share


4 answers


[0..]

- syntactic sugar for enumFrom 0

, defined in the class Enum

. Since you want to generate a list a

with [0..]

, the compiler requires to a

be in a class Enum

.

You can either add Enum a

to the type signature of the function, or work around it by creating [0..] :: [Integer]

and using fromInteger

(which is defined in the class Num

) to get [a]

from that:



diff :: (Num a) => [a] -> [a]
diff [] = error "Polynomial unspecified"
diff coeff = zipWith (*) (tail coeff) (map fromInteger [0..])

      

+8


source


The correct type diff

should be

diff :: (Num a, Enum a) => [a] -> [a]

      



because [x..]

it requires a type to be instantiated to use Enum

.

+7


source


[0..]

is shorthand for enumFrom 0

See here

+3


source


Here's a quick summary of what the compiler sees when it looks at this function:

  • [0 ..] is a list of things that have instances of Num and Enum. It must be Num because of "0" and it must be Enum because of ".."
  • I am being asked to apply (*) to coeff and [0 ..] elements one by one. Since both arguments to (*) must be of the same type and [0 ..] is instantiated for Enum, coeff must also be instantiated for Enum.
  • Mistake! The typical diff signature only mentions that coeff has an instance for Num, but I already figured it should at least have an instance for Enum too.
+2


source







All Articles