haskell - 如何解决 haskell 中的模棱两可的类型运行时错误?
问题描述
我有这个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)
但是当我像这样运行它时:getNumb 10
我收到此错误:
<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
据我了解,问题在于函数的返回类型与输入类型不兼容。这个对吗?如果是,我该如何解决?
注意:这是的输出,:t
据推测返回一个是正确的Integer
*Main> :t getNumb
getNumb
:: (RealFrac t, Floating t, Integral p, Integral t) => t -> p
解决方案
计算对数是一种低效的求值方法。相反,沿着“树”向下工作,并在备份的路上计算索引。这仅需要Integral
对参数进行约束,因为除了将其除以 2 之外,您从不做任何事情。
请注意,所有偶数指数都为 2;奇数是递归计算的。
getNumb theta | even theta = 2
| otherwise = 1 + getNumb (theta `quot` 2)
even
是根据 , 实现的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]
推荐阅读
- java - 在 Java Android 问题中从 HTTP (retrofit2) 响应下载 PDF 文件?
- wordpress - Wordpress:301 从本地主机重定向到域名
- mysql - Rails 中的悲观锁定 with_lock
- sql-server - 除非SSRS中每组有2行,否则如何隐藏行?
- c - 关于查找表和array[char a]含义的C编程题
- c - C - 用单个出现替换字符的多个连续出现
- stata - 输出带边距的变量值标签,dydx()
- r - 闪亮如何确定依赖关系
- python-3.x - 无法使用 pyarrow 从目录中读取镶木地板文件
- javascript - MVC:鉴于模型的属性是异步获取的,如何在控制器的构造函数中记录模型属性的值?