我太困了以至于我编写了以下代码(修改后只显示了混淆):
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
这不是指以下内容:
fac
的第一个输入必须是类型Integral
(例如fac 10
); maxFactor
的定义中,有fac x
,x也必须是类型Integral
,因此,maxFactor
的类型将以类似的方式开头maxFactor :: (Integral a) => a ->
...那么别的什么?但是,如果是这种情况,那么为什么此代码编译,因为maxFactor
的返回可以是x
或head
,这在遵循这一推理线时,不具有相同的类型?我在这里缺少什么?
感谢提前输入任何内容!
答案 0 :(得分:11)
正如您已经注意到的那样,在fac
内使用功能maxFactor
会对Integral a
的类型添加x
约束。因此x
必须是Integral a => a
类型。
此外,编译器会看到maxFactor
返回head
,其类型为[a]->a
或x
。因此,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这一事实更像是解释器的一个怪癖。如果您只是编译上面的代码,它将会失败。
编辑:我想问题是类型检查器可以理解你的代码,但是可能没有任何合理的方法来使用它。