如何解决haskell中的模糊类型运行时错误?
我有一个haskell函数,它计算无限列表中给定位置的数字:如何解决haskell中的模糊类型运行时错误?,haskell,types,Haskell,Types,我有一个haskell函数,它计算无限列表中给定位置的数字: [2,3,2,4,2,3,2,5,2,3,2,4,2,3,2,...] 因此,对于第n个新数字,列表将是l(n-1)+[n]++l(n-1)。 我已实现此功能: getNumb theta = if ((floor (logBase 2 theta)) == ceiling (logBase 2 theta)) then (floor (logBase 2 theta)) + 2
[2,3,2,4,2,3,2,5,2,3,2,4,2,3,2,...]
因此,对于第n个新数字,列表将是l(n-1)+[n]++l(n-1)。
我已实现此功能:
getNumb theta = if ((floor (logBase 2 theta)) == ceiling (logBase 2 theta))
then (floor (logBase 2 theta)) + 2
else getNumb (2*(floor (logBase 2 theta)) - theta)
但是当我像这样运行它时:getnumb10
我得到这个错误:
<interactive>:3:1: error:
* Could not deduce (RealFrac t0) arising from a use of `getNumb'
from the context: Integral p
bound by the inferred type of it :: Integral p => p
at <interactive>:3:1-10
The type variable `t0' is ambiguous
These potential instances exist:
instance RealFrac Double -- Defined in `GHC.Float'
instance RealFrac Float -- Defined in `GHC.Float'
...plus one instance involving out-of-scope types
(use -fprint-potential-instances to see them all)
* In the expression: getNumb 10
In an equation for `it': it = getNumb 10
<interactive>:3:9: error:
* Could not deduce (Num t0) arising from the literal `10'
from the context: Integral p
bound by the inferred type of it :: Integral p => p
at <interactive>:3:1-10
The type variable `t0' is ambiguous
These potential instances exist:
instance Num Integer -- Defined in `GHC.Num'
instance Num Double -- Defined in `GHC.Float'
instance Num Float -- Defined in `GHC.Float'
...plus two others
...plus two instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
* In the first argument of `getNumb', namely `10'
In the expression: getNumb 10
In an equation for `it': it = getNumb 10
计算对数是一种效率低下的求值方法。相反,沿着“树”往下走,在返回的过程中计算索引。这只需要对参数设置一个
Integral
约束,因为除了将它除以2之外,你什么都不做
请注意,所有偶数指数的值均为2;奇数是递归计算的
getNumb theta | even theta = 2
| otherwise = 1 + getNumb (theta `quot` 2)
甚至
都是根据rem
实现的,而quot
和rem
都只是quotRem
的包装,因此您可能只需要自己调用quotRem
getNumb theta = case quotRem theta 2 of
(_, 0) -> 2
(q, _) -> 1 + getNum q
为了证明这一点,请注意,您可以将函数映射到自然数上,以返回原始列表:
> map getNumb [0..30]
[2,3,2,4,2,3,2,5,2,3,2,4,2,3,2,6,2,3,2,4,2,3,2,5,2,3,2,4,2,3,2]
这不是运行时错误,而是编译错误。编译步骤之后,类型“消失了”。getNumb的签名给出了答案。t应该是
整数
和浮动
Double
是一个实例Floating
而不是Integral
Int
是Integral
notFloating
> map getNumb [0..30]
[2,3,2,4,2,3,2,5,2,3,2,4,2,3,2,6,2,3,2,4,2,3,2,5,2,3,2,4,2,3,2]