如何在Haskell中处理严格的类型检查?

时间:2018-06-09 09:57:41

标签: haskell

我试图在Haskell中编写我的第一个程序(它非常简单) 检查给定的数字是否为素数:

prime :: Num n=> n -> Bool
prime x=smz[x `mod` a > 0 | a<-[2..(round(sqrt x))]] where
        smz :: [Bool]->Bool
        smz [] = True
        smz (c:cs)=c && (smz cs)

但我遇到了一堆错误。有人可以给我正确的代码版本(不改变我的想法)

2 个答案:

答案 0 :(得分:4)

GHC中的编译错误包含实际描述,也包含源位置。一些较新的ghc版本也会打印一段代码。此外,还有其他信息添加到错误消息中,因此整体看起来相当可怕。但实际错误在第一行。最简单的是类型不匹配,比如&#34;期待这个,得到那个&#34;。在复杂的情况下,您可能需要检查文档,Google或SO。

从第一个错误开始通常会更好。有时它们很明显可以解决。有时他们会让你重新考虑你的设计。在修复错误后再次编译并选择下一个。继续,直到所有错误都得到修复。

有些人还建议先不要编写很多代码然后编译并获取大量错误,但要尽量少写,然后编译。这样每个步骤的错误就会减少。

答案 1 :(得分:3)

  1. 您的smz功能已存在于标准Prelude中,并且名为and
  2. mod只能与Integralmod :: Integral a => a -> a -> a一起使用,这意味着您无法使用必须为Floating的x由于sqrt :: Floating a => a -> a,因此您处于一种情况,即x必须是Integral(例如Int)和浮点数。这是不可能的!

    有一个解决方案。你必须在任何一个地方转换任何一个。我建议您在将fromIntegral推送到sqrt之前转换where。这也意味着您的函数类型签名将会更改,您应该只删除当前的签名并亲自查看。

  3. 除此之外,您可能希望将<{1}}子句保留在函数声明中,如下所示:

    foo x = ...
       where
         baz n = ...