简体   繁体   English

为什么Haskell将我的Num类型解释为Enum?

[英]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: 我正在尝试在Haskell中编译以下函数,以模仿在数值列表中指定常量的多项式的区分:

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: Haskell拒绝编译它,给出了以下原因:

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. 为什么Haskell将[0..]列表视为Enum类型,我该如何解决这个问题。 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 . [0..]enumFrom 0语法糖,在Enum类中定义。 Because you want to generate a list of a s with [0..] the compiler demands a to be in class Enum . 因为要生成的列表a以s [0..]编译器需要a要在类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: 您可以将Enum a添加到函数的类型签名中,也可以通过生成[0..] :: [Integer]并使用fromInteger (在类Num定义)从中获取[a]来解决该问题。 :

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类型

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

because the usage of [x..] requires the type to instantiate Enum . 因为[x..]要求类型实例化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. [0 ..]是包含Num和Enum实例的事物的列表。 It has to be a Num because of the '0', and it has to be an Enum because of the '..' 由于'0',它必须是一个Num,并且因为'..'而必须是一个Enum。
  • I'm being asked to apply (*) to the elements of coeff and [0..] one by one. 我被要求逐一将(*)应用于coeff和[0 ..]的元素。 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. 由于(*)的两个参数必须是相同的类型,并且[0 ..]具有Enum的实例,因此coeff还必须具有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. diff的类型签名只提到coeff有一个Num实例,但我已经确定它至少也必须有一个Enum实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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