开发者

Why does Haskell interpret my Num type as an Enum?

I'm trying to compile the following function in Haskell to mimic differentiation of a polynomial whose constants are specified in a numerical 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 ded开发者_开发问答uce (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 is Haskell treating the [0..] list as an Enum type, and how can I fix this. Bear in mind that I want to take advantage of lazy evaluation here, hence the infinite list.


[0..] is syntactic sugar for enumFrom 0, defined in class Enum. Because you want to generate a list of as with [0..] the compiler demands a to be in class Enum.

You can either add the Enum a to the type signature of the function or work around it by generating a [0..] :: [Integer] and using fromInteger (which is defined in class Num) to get a [a] from that:

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


The correct type of diff has to be

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

because the usage of [x..] requires the type to instantiate Enum.


[0..] is shorthand for enumFrom 0 See here


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

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜