代码之家  ›  专栏  ›  技术社区  ›  Zaid

为什么Haskell将我的num类型解释为枚举?

  •  2
  • Zaid  · 技术社区  · 15 年前

    我试图在haskell中编译以下函数,以模拟一个多项式的微分,该多项式的常数在数字列表中指定:

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

    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 .. ])
    

    为什么哈斯克尔治疗 [0..] 作为枚举类型列出,以及如何修复此问题。记住,我想利用这里懒惰的评价,从而得到无限的清单。

    4 回复  |  直到 13 年前
        1
  •  8
  •   yfeldblum    15 年前

    [0..] 句法上的糖分 enumFrom 0 ,在类中定义 Enum . 因为你想生成一个 a 带着 〔0〕 编译器要求 上课 枚举 .

    您可以添加 Enum a 函数的类型签名或通过生成 [0..] :: [Integer] 并使用 fromInteger (在类中定义) Num 为了得到一个 [a] 从:

    diff :: (Num a) => [a] -> [a]
    diff [] = error "Polynomial unspecified"
    diff coeff = zipWith (*) (tail coeff) (map fromInteger [0..])
    
        2
  •  7
  •   Dario    15 年前

    正确的类型 diff 必须是

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

    因为使用 [x..] 需要类型来实例化 Enum .

        3
  •  3
  •   newacct    15 年前

    [0..] enumFrom 0 See here

        4
  •  2
  •   Michael Steele    15 年前

    以下是编译器查看此函数时看到的内容的快速摘要:

    • [0..]是同时具有num和enum实例的列表。因为“0”,它必须是一个num,因为“0”,它必须是一个枚举。
    • 我被要求对coeff和[0..]的元素逐一应用(*)。由于(*)的两个参数必须是同一类型并且[0..]具有枚举的实例,因此coeff还必须具有枚举的实例。
    • 错误!diff的类型签名只提到coeff有一个num实例,但我已经确定它至少也必须有一个num实例。