简体   繁体   中英

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 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 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 a s 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..]enumFrom 0缩写, 请参见此处

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM