haskell - Haskell素数生成器错误

标签 haskell compiler-errors primes

我试过了:

composites=[c|c<-[4..], any (\p->(c`mod`p == 0)) (takeWhile (< (sqrt c)) primes)]
primes=2:[p|p<-[3..], not p `elem` (takeWhile (<p) composites)]

并得到:
pad.hs:1:19:
    No instance for (Num Bool) arising from the literal `4'
    Possible fix: add an instance declaration for (Num Bool)
    In the expression: 4
    In the expression: [4 .. ]
    In a stmt of a list comprehension: c <- [4 .. ]

pad.hs:1:30:
    No instance for (Integral Bool) arising from a use of `divisible'
    Possible fix: add an instance declaration for (Integral Bool)
    In the first argument of `any', namely `(divisible c)'
    In the expression: any (divisible c) (factors c)
    In a stmt of a list comprehension: any (divisible c) (factors c)

pad.hs:3:43:
    No instance for (Floating Bool) arising from a use of `sqrt'
    Possible fix: add an instance declaration for (Floating Bool)
    In the second argument of `(<)', namely `sqrt c'
    In the first argument of `takeWhile', namely `(< sqrt c)'
    In the expression: takeWhile (< sqrt c) primes
Failed, modules loaded: none.

我认为它处理的是什么类型的数字感到困惑,但我不确定。有小费吗?

最佳答案

I think that it is confused as to what type of number it is dealing with



非常正确!那你为什么不告诉呢?在实际实现之前,最好在Haskell中编写函数签名。这不仅可以防止发生错误时引起混淆的编译器消息,而且还为实际设计函数提供了非常好的指南。

因此,就您而言,您可能想要1
composites, primes :: [Integer]

哪个当然不能解决问题,但可以使错误消息更加清晰:

Prelude> let composites,primes::[Integer]; composites=[c|c<-[4..], any (\p -> c`mod`p == 0) (takeWhile (< sqrt c) primes)]; primes=2:[p|p<-[3..], not p `elem` (takeWhile (< p) composites)]

<‌interactive>:2:128:
    Couldn't match expected type `Integer' with actual type `Bool'
    In the expression: p
    In the second argument of `(:)', namely
      `[p | p <- [3 .. ], not p `elem` (takeWhile (< p) composites)]'
    In the expression:
      2 : [p | p <- [3 .. ], not p `elem` (takeWhile (< p) composites)]

<‌interactive>:2:169:
    Couldn't match type `Integer' with `Bool'
    Expected type: [Bool]
      Actual type: [Integer]
    In the second argument of `takeWhile', namely `composites'
    In the second argument of `elem', namely
      `(takeWhile (< p) composites)'
    In the expression: not p `elem` (takeWhile (< p) composites)



仍然不是很准确,但是至少现在可以将错误定位到它的位置:在primes中,p推断为Bool,这当然是错误的。出现bool的原因是您在那里有not p `elem` (...)。显然您认为这被解析为not (p`elem`(...)),但事实并非如此:普通前缀函数应用程序的优先级高于任何infix运算符。要知道的一件事很重要(这也是为什么您不需要在sqrt c中的(< sqrt c)周围加括号的原因)。

解决这个问题,然后还有一个问题:

Prelude> let composites,primes::[Integer]; composites=[c|c<‌-[4..], any (\p->(c`mod`p == 0)) (takeWhile (<‌ (sqrt c)) primes)]; primes=2:[p|p<‌-[3..], not $ p `elem` (takeWhile (<‌p) composites)]

<‌interactive>:3:99:
    No instance for (Floating Integer) arising from a use of `sqrt'
    Possible fix: add an instance declaration for (Floating Integer)
    In the second argument of `(<‌)', namely `(sqrt c)'
    In the first argument of `takeWhile', namely `(<‌ (sqrt c))'
    In the second argument of `any', namely
      `(takeWhile (<‌ (sqrt c)) primes)'



现在就可以了:您正在处理整数,但是sqrt显然会产生通常不合理的数字,因此只有Floating类型才有意义。为了解决这个问题,您可以使用sqrt' = round . sqrt . fromIntegral(非常难看,但是可以)。

1实际上,这种单态签名可能并不理想-出于各种原因(主要是效率),您可能更喜欢Int。为了安全起见,请选择Integral a => [a];但是,多态值不会在顶层“存储”,这在此示例中再次成为问题。

关于haskell - Haskell素数生成器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19737866/

相关文章:

haskell - 我应该避免使用交互模式吗?

haskell - 在编程语言和范例的上下文中, "Pure"是什么意思?

Haskell:无法匹配预期的类型错误

linux - 如何让 gcc 跳过错误,但仍然输出它们。

java - 无法将我的 DefaultListModel 分配给 Java NetBeans 中的 JList

c - 两个连续质数之间的最大差值

algorithm - 如何找到给定数量的素数?

haskell - 如何使用 "cabal configure"/Setup.hs 进行本地构建?

clojure - #'namespace/name_of_function中的错误

python - 循环列表与范围时的行为差异