Haskell:为什么没有类型不匹配(为什么编译)?

时间:2012-04-10 15:40:02

标签: haskell types ghc typeclass ghci

我太困了以至于我编写了以下代码(修改后只显示了混淆):

fac s = take 10 [s, s `mod` 1 ..]

maxFactor x = if (s == [])
              then x
              else head    <-- this should be 'head x' instead of just 'head'
  where s = fac x

但是,这个加载到ghci(和编译)就好了。当我执行maxFactor 1时,它会抱怨(当然):

<interactive>:0:1:
    No instance for (Integral ([a0] -> a0))
      arising from a use of `maxFactor'
    Possible fix:
      add an instance declaration for (Integral ([a0] -> a0))
    In the expression: maxFactor 1
    In an equation for `it': it = maxFactor 1

<interactive>:0:11:
    No instance for (Num ([a0] -> a0))
      arising from the literal `1'
    Possible fix: add an instance declaration for (Num ([a0] -> a0))
    In the first argument of `maxFactor', namely `1'
    In the expression: maxFactor 1
    In an equation for `it': it = maxFactor 1

但是,我不明白这种行为:

fac的类型是:

fac :: Integral a => a -> [a]

maxFactor的类型是:

maxFactor :: Integral ([a] -> a) => ([a] -> a) -> [a] -> a

这不是指以下内容:

  1. fac的第一个输入必须是类型Integral(例如fac 10);
  2. 因为在maxFactor的定义中,有fac x,x也必须是类型Integral,因此,maxFactor的类型将以类似的方式开头maxFactor :: (Integral a) => a -> ...那么别的什么?但是,如果是这种情况,那么为什么此代码编译,因为maxFactor的返回可以是xhead,这在遵循这一推理线时,不具有相同的类型?
  3. 我在这里缺少什么?

    感谢提前输入任何内容!

2 个答案:

答案 0 :(得分:11)

正如您已经注意到的那样,在fac内使用功能maxFactor会对Integral a的类型添加x约束。因此x必须是Integral a => a类型。

此外,编译器会看到maxFactor返回head,其类型为[a]->ax。因此,x必须具有更具体的类型Integral ([a]->a) => ([a]->a),因此maxFactor具有类型

maxFactor :: Integral ([a] -> a) => ([a] -> a) -> ([a] -> a)

这正是你得到的。什么都没有&#34;错误&#34;到目前为止这个定义。如果您设法编写Integral类型([a]->a)的实例,则可以毫无问题地调用maxFactor。 (显然maxFactor不会按预期工作。)

答案 1 :(得分:9)

maxFactor中,编译器推断函数参数x必须与head具有相同的类型(在if子句中)。由于您还在fac上调用x(后者又调用mod),因此它会推断x也是某种Integral类类型。因此,编译器推断出类型

maxFactor :: Integral ([a] -> a) => ([a] -> a) -> [a] -> a

需要一些head - 类似于整数的参数......这不太可能是真实的。

我认为你可以将代码加载到GHCi这一事实更像是解释器的一个怪癖。如果您只是编译上面的代码,它将会失败。

编辑:我想问题是类型检查器可以理解你的代码,但是可能没有任何合理的方法来使用它。

相关问题