gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 02:50:10 25 4
gpt4 key购买 nike

我今天用 Haskell 编写了我的第一个程序。 It compiles and runs successfully .由于它不是一个典型的“Hello World”程序,它实际上做的远不止这些,所以请恭喜我 :D

无论如何,我对我的代码和 Haskell 中的语法几乎没有怀疑。

问题:

我的程序读取一个整数 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

它工作得很好。但我怀疑第一行是多次尝试的结果,正如我在 this tutorial 中读到的那样没有用,并给出了这个错误(我想这是一个错误,虽然它没有这么说):
prime.hs:9:13:
Type constructor `Integer' used as a class
In the type signature for `is_prime':
is_prime :: Integer a => a -> Bool

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

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

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

另外,循环遍历 1 的惯用方法是什么?至 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 类型的值.
  • 什么是a ?它可以是实现 Integral 的调用者选择的任何类型。类型类,如 IntegerInt .

  • (还有 IntInteger 的区别?后者可以表示任意大小的整数,前者最终会回绕,类似于 C/Java/etc 中的 int s)

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

    您在 main 中的循环是一张 map ,因为你在循环中做 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 这样的名称。)

    关于function - `(Integer a) => a -> Bool` 和 ` Integer -> Bool` 之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11275805/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com