首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不明确的类型变量

不明确的类型变量
EN

Stack Overflow用户
提问于 2012-09-10 22:45:59
回答 1查看 116关注 0票数 2

我写了一个小的haskell程序,它只计算一个数字(Int)中有多少个1。当我尝试执行它时,haskell抱怨变量约束不明确。我知道它来自于地板的使用。我也读了一些关于stackoverflow的答案。但我真的没有找到解决这个问题的办法。下面是我的代码:

代码语言:javascript
复制
count_ones = count_ones' 0

count_ones' m 0 = m
count_ones' m n | n-10*n_new == 1 = count_ones' (m+1) n_new
                | otherwise         = count_ones' m n_new
                 where n_new = floor (n/10)

有什么建议吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-09-10 22:52:27

代码语言:javascript
复制
count_ones' m n | n-10*n_new == 0.1 = count_ones' (m+1) n_new
                | otherwise         = count_ones' m n_new
                 where n_new = floor (n/10)

在第一行中,您将n - 10*n_new与分数字面量0.1进行比较,因此nn_new的类型必须是Fractional类的成员。

where子句中,您绑定了n_new = floor (n/10),因此n_new的类型必须是Integral类的成员。

由于没有标准类型是这两个类的成员(有充分的理由),编译器无法解析约束

代码语言:javascript
复制
(Fractional a, Integral a) => a

当函数被调用时。

如果为函数提供类型签名,编译器通常会生成更有用的错误消息。

解决此问题的最简单方法是将n_new的绑定更改为

代码语言:javascript
复制
n_new = fromIntegral (floor $ n/10)

考虑到您在注释中说0.1是一个错误,您应该使用1,那么您可能只想使用Integral类型,代码的最接近的转录本应该是

代码语言:javascript
复制
count_ones' :: Integral a => Int -> a -> Int
count_ones' m 0 = m
count_ones' m n
    | n - 10*n_new == 1 = count_ones' (m+1) n_new
    | otherwise         = count_ones' m n_new
      where
        n_new = n `div` 10

但将条件n - 10*n_new == 1替换为n `mod` 10 == 1可能会更清楚。

然而,这将需要每一步两个分区,这可能效率较低。使用divMod应该只给出一个除法指令的商和除法的余数,

代码语言:javascript
复制
count_ones' m n = case n `divMod` 10 of
                    (q,1) -> count_ones' (m+1) q
                    (q,_) -> count_ones' m q

如果你能保证你只会用非负的n调用函数,那就使用quotrem nquotRem代替了divmoddivMod。前者直接使用机器除法指令的结果,而后者则需要进行一些后处理,以确保mod的结果是非负的,因此quot和friends比div和company更高效。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12354089

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档