如何解决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

我有一个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
              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
not
Floating
> 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]