`(Integer a) => a -> Bool` 和 `Integer -> Bool` 之间的区别?

2023-12-11

今天我用 Haskell 写了第一个程序。编译并运行成功。而且由于它不是典型的“你好世界”程序,它实际上做的远不止这些,所以请祝贺我:D

不管怎样,我对我的代码和 Haskell 中的语法没有什么疑问。

Problem:

我的程序读取一个整数N从标准输入,然后,对于每个整数i在范围中[1,N],它打印是否i是否是质数。目前它不检查输入错误。 :-)

解决方案:(也有疑问/问题)

为了解决这个问题,我编写了这个函数来测试整数的素数:

is_prime :: Integer -> Bool
is_prime n = helper n 2
        where
          helper :: Integer -> Integer -> Bool
          helper n i  
              | n < 2 * i = True
              | mod n i > 0 = helper n (i+1)
              | otherwise = False

效果很好。但我怀疑第一行是多次尝试的结果,正如我在本教程没有工作,并给出了这个错误(我suppose这是一个错误,尽管它没有这么说):

prime.hs:9:13:
    Type constructor `Integer' used as a class
    In the type signature for `is_prime':
      is_prime :: Integer a => a -> Bool

根据教程(顺便说一句,这是一个写得很好的教程),第一行应该是:(教程说(Integral a) => a -> String, 所以我认为(Integer a) => a -> Bool应该也能工作。)

is_prime :: (Integer a) => a -> Bool

这不起作用,并给出上面发布的错误(?)。

为什么它不起作用?这条线(不起作用)和这条线(起作用)有什么区别?


另外,循环的惯用方法是什么1 to N?我对代码中的循环并不完全满意。请提出改进​​建议。这是我的代码:

--read_int function
read_int :: IO Integer
read_int = do
     line <- getLine
     readIO line

--is_prime function
is_prime :: Integer -> Bool
is_prime n = helper n 2
        where
          helper :: Integer -> Integer -> Bool
          helper n i  
              | n < 2 * i = True
              | mod n i > 0 = helper n (i+1)
              | otherwise = False

main = do
       n <- read_int
       dump 1 n
       where
           dump i x = do 
                 putStrLn ( show (i) ++ " is a prime? " ++ show (is_prime i) )
                 if i >= x 
                    then putStrLn ("")
                  else do
                    dump (i+1) x

您误读了教程。它会说类型签名应该是

is_prime :: (Integral a) => a -> Bool
--       NOT Integer a

这些是不同的类型:

  • Integer -> Bool
    • 这是一个采用类型值的函数Integer并返回一个类型的值Bool.
  • Integral a => a -> Bool
    • 这是一个采用类型值的函数a并返回一个类型的值Bool.
    • What is a?它可以是调用者选择的实现以下功能的任何类型Integral类型类,例如Integer or Int.

(以及之间的区别Int and Integer?后者可以表示任意大小的整数,前者最终会回绕,类似于intC/Java/等)


惯用的循环方式取决于循环的作用:它可以是地图、折叠或过滤器。

你的循环main是一个地图,因为你在循环中进行 i/o,所以你需要使用mapM_.

let dump i = putStrLn ( show (i) ++ " is a prime? " ++ show (is_prime i) )
 in mapM_ dump [1..n]

同时,你的循环is_prime是一个折叠(具体来说all在这种情况下):

is_prime :: Integer -> Bool
is_prime n = all nondivisor [2 .. n `div` 2]
        where
          nondivisor :: Integer -> Bool
          nondivisor i = mod n i > 0

(在风格上的一个小问题上,Haskell 中通常使用这样的名称isPrime而不是像这样的名字is_prime.)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

`(Integer a) => a -> Bool` 和 `Integer -> Bool` 之间的区别? 的相关文章

随机推荐

  • 为什么只有一个空数组的数组长度为0?

    The Length属性在我测试的所有数组上都按预期工作 除了一种奇怪的情况 PS gt Length 0 但这并不是说空数组通常会被省略 PS gt Length 2 PS gt Length 3 这是怎么回事 the 数组子表达式运算符
  • 合并 django 查询集上的行

    我有一个带有属性位置 人员和错误的查询集 我需要创建一个新的查询集或编辑现有的查询集 以便根据特定条件 组合 行 该标准是位置和人物是否相同 合并后 如果要合并的任何行具有真值 我希望使错误值为真 在这种情况下 该表应更改如下 Locati
  • VBS将字符串转换为浮点数

    Dim strnumber strnumber 0 3 Dim add add 0 1 Dim result result strnumber add MsgBox result 我想要得到0 4结果 但得到3 1 我试过clng strn
  • JAX-RS异常:用资源的GET注释,类未被识别为有效的资源方法

    我正在将 JAX RS 的球衣实现用于 Web 服务 我对这个 JAX RS 很陌生 我正在尝试在服务中添加一个方法 该方法接受 Employee 对象并根据 Employee 对象值返回员工 ID 为此有一个数据库命中 遵循Restful
  • hg clone 相当于 hg (init→pull)

    在工作中我正在使用svn存储库由 7 个人共享 为了避免因提交而困扰我的错误并破坏每个人的构建 并避免分支svn 我创建了一个hg存储库的一部分svn我目前正在处理的目录 我在工作时在 hg 上执行本地提交 因为我在虚拟机上完成了所有设置
  • 如何根据联系人 ID 显示联系人的照片?

    这段代码 在我的定制适配器class 仅根据向我发送短信的人显示联系人 ID 并将其放入 ArrayList 然后显示列表 我有一个名为的 ImageViewholder photo每个联系人 ID 旁边 我将如何在 ImageView 中
  • 如何创建可变数量的 RichTextBox Overflow 元素

    我正在尝试以各种方式摆脱必须创建多个的循环RichTextBlockOverflow基于任意输入文本长度的控件但没有成功 这HasOverflowContent属性不会同步或异步更新 变量 bool ThereIsText 我无法理解何时以
  • pyFirmata 给出错误:模块“inspect”没有属性“getargspec”

    我正在尝试使用皮尔玛塔 但我无法让它工作 即使是最基本的库也不起作用 我猜库代码有问题 from pyfirmata import Arduino util import time port COM5 board Arduino port
  • 以管理员身份使用 Azure DevOps 命令行

    我想在 azure devops 发布管道中使用 cmd 任务停止 Topshelf 服务 我所做的是创建 CommandLineTask 其脚本如下 ServiceName exe 停止 作为输出我看到 v3 1 4 2020 06 05
  • Bash - 将变量连接到路径上

    目前 我有一个 bash 脚本 它将在我的根目录中解压文件 bin bash tar xvf some file tar 这工作没有问题 现在 我想更改此设置 以便可以在预定义变量中指定文件的路径 如下所示 bin bash p tar x
  • OverflowException 仅在 VB.net 中出现,在 C# 中没有

    出于自我教育的目的 我试图找到一种自己创建高度图的方法 我用谷歌搜索了一下 发现了一个创建伪随机数的函数 public static float Noise int x x x lt lt 13 x return 1f x x x 1573
  • 如何将React-Native中的字符串变成组件?

    我有一个var str
  • 即使 strlen 在可接受的范围内,此正则表达式也会截断字符串中的最后一个单词

    theExcerpt Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod tempor incididunt ut labore et dolore
  • SQL 查询提取当月数据

    我想要对处置进行计数 并且只计算当月的处置 这是我的代码 SELECT Disposition COUNT Disposition AS Count Date FROM CSLogs dbo Logs GROUP BY Dispositio
  • 将文本写入文件的中间

    有没有办法可以从文件中的某个点将文本写入文件 例如 我打开一个包含 10 行文本的文件 但我想在第 5 行写入一行文本 我想一种方法是使用 readalllines 方法将文件中的文本行作为数组返回 然后在数组中的某个索引处添加一行 但有一
  • 为什么 Python 中的列表理解比 map() 更快?

    我正在研究Python中类似循环结构的性能问题 发现以下语句 除了列表推导式的语法优势之外 它们通常还 与同等使用地图一样快或更快 性能技巧 列表推导式的运行速度比等效的 for 循环要快一些 除非 你只会丢弃结果 蟒蛇速度 我想知道幕后的
  • Docker compose mysql 连接失败

    我正在尝试使用 docker compose 运行 2 个 docker 容器并将 mysql 容器连接到应用程序容器 Mysql 容器正在运行 但应用程序容器无法启动并出现错误错误 2003 无法连接到 127 0 0 1 3306 上的
  • 如何删除二维向量中的列,C++

    如果我在创建矩阵的向量中有一个向量 如何删除该矩阵中的特定列 我已经填充了二维向量 现在我需要一种方法来删除该向量中的特定列 例如我的向量看起来像 vector
  • Python:与 urljoin 的混淆

    我正在尝试从不同的部分形成 URL 但无法理解此方法的行为 例如 Python 3 x from urllib parse import urljoin gt gt gt urljoin some thing thing gt gt gt
  • `(Integer a) => a -> Bool` 和 `Integer -> Bool` 之间的区别?

    今天我用 Haskell 写了第一个程序 编译并运行成功 而且由于它不是典型的 你好世界 程序 它实际上做的远不止这些 所以请祝贺我 D 不管怎样 我对我的代码和 Haskell 中的语法没有什么疑问 Problem 我的程序读取一个整数N