11

我太困了,我写了以下代码(修改以显示混乱):

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]

whilemaxFactor的类型是:

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

这是否意味着以下内容:

  1. 的第一个输入fac必须是类型类Integral(例如,fac 10);
  2. 因为在 的定义中maxFactorfac x, x 也必须是 typeclass Integral,因此,maxFactor的类型将以maxFactor :: (Integral a) => a ->... 开头,然后是其他的?但是,如果是这样的话,那么为什么这段代码会编译,因为maxFactorcan be xor的返回head,当遵循这条推理时,它不具有相同的类型?

我在这里想念什么?

感谢您提前提供任何输入!

4

2 回答 2

11

正如您正确注意到的那样,在fac内部使用函数maxFactor会增加Integral ax. 所以x需要是 type Integral a => a

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

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

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

于 2012-04-10T16:19:07.507 回答
9

maxFactor编译器中推断出函数参数必须具有与(在您的子句中)x相同的类型。由于您还调用on (反过来调用)它推断这也是某种类类型。因此,编译器推断类型headiffacxmodxIntegral

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

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

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

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

于 2012-04-10T15:54:49.623 回答