【发布时间】:2012-04-10 15:40:01
【问题描述】:
我太困了,写了以下代码(为了显示混乱而修改):
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,按照这种推理,它们的类型不一样?
我在这里错过了什么?
提前感谢您的任何意见!
【问题讨论】:
-
这种问题可能以更简单的方式出现。我怀疑(但我不是专家)只要类型检查器无法充分减少表达式,就会发生这种情况。例如, foo x = 1 + x; bar = foo head -- 会失败,但是 foo x = 1 + x; bar x = foo head -- 将编译。
-
@Sarah:由于单态限制,您提供的示例没有进行类型检查;如果添加 pragma,它会进行类型检查(不过有一个微妙的问题:GHCi 推断类型
Num ([a] → a) ⇒ [a] → a并且您不能使用此类型声明bar,您需要 FlexibleContexts)。 -
不管怎样,如果你使用
-Wall编译(或将其添加到默认的 ghci 选项中,以便 ghci 使用-Wall“编译”)你会收到一个警告,因为你没有不要在maxFactor上添加类型签名。然后,大概你会写maxFactor :: Integral a => a -> a,它会编译失败。
标签: haskell types ghc typeclass ghci