这是Haskell中的函数吗?如果是,我们应该如何阅读?

这是Haskell中的函数吗?如果是,我们应该如何阅读?,haskell,recursion,primes,lazy-evaluation,Haskell,Recursion,Primes,Lazy Evaluation,在Doets等人的Haskell Road to Logic,Math and Programming一书第103页中,给出了 prime :: Integer -> Bool prime n | n < 1 = error "not a positive integer" | n == 1 = False | otherwise = ldp n == n where ldp = ldpf primes ldpf (p:p

在Doets等人的Haskell Road to Logic,Math and Programming一书第103页中,给出了

prime :: Integer -> Bool
prime n | n < 1     = error "not a positive integer"
        | n == 1    = False
        | otherwise = ldp n == n where 
  ldp    = ldpf primes
  ldpf (p:ps) m | rem m p == 0 = p
                | p^2 > m = m
                | otherwise = ldpf ps m 
  primes = 2 : filter prime [3..]
prime::Integer->Bool
素数n | n<1=错误“不是正整数”
|n==1=False
|否则=ldp n==n,其中
ldp=ldpf素数
ldpf(p:ps)m | rem m p==0=p
|p^2>m=m
|否则=ldpf ps m
素数=2:过滤器素数[3..]
然而,这个函数的逻辑不是循环的吗?我的意思是我认为我对递归函数很熟悉,但我不认为这是一个递归函数。即使是这样,我也无法理解它的逻辑,所以我的问题是如何理解这样一个函数的逻辑

编辑:


我感到困惑的原因是
prime
函数使用list
primes
,但要生成该列表,我们还使用函数
prime
,因此似乎存在循环逻辑,或者我只是不理解带延迟求值的递归函数。

ldp n==n条件可以等效地重新编写为

ldpf primes n == n
=
null [() | p <- takeWhile (\p -> p^2 <= n) primes, rem n p==0]
=
and [rem n p > 0 | p <- takeWhile (\p -> p^2 <= n) primes]
直到最小素数
q>下限(sqrt$from integral n)
,并且仅需要不大于
q
平方根的素数。要生成这些,只需要不大于其平方根的数字。很快我们就不再需要任何素数了,例如

prime 3
= 
ldpf primes 3 == 3
=
and [rem 3 p > 0 | p <- takeWhile (\p -> p^2 <= 3) (2 : filter prime [3..])]
= 
and [rem 3 p > 0 | p <- takeWhile (<= 3) (4 : 
                                      map (\p -> p^2) (filter prime [3..]))]
= 
and [rem 3 p > 0 | p <- []]
=
and []
=
True
之后,我们可以在GHCi提示下进行检查

> :sprint primes
2 : 3 : _

(为了使上述方法有效,您需要从
prime
函数中取出
primes
,并使其本身成为顶级实体)。

ldp n==n条件可以等效地重新编写为

ldpf primes n == n
=
null [() | p <- takeWhile (\p -> p^2 <= n) primes, rem n p==0]
=
and [rem n p > 0 | p <- takeWhile (\p -> p^2 <= n) primes]
直到最小素数
q>下限(sqrt$from integral n)
,并且仅需要不大于
q
平方根的素数。要生成这些,只需要不大于其平方根的数字。很快我们就不再需要任何素数了,例如

prime 3
= 
ldpf primes 3 == 3
=
and [rem 3 p > 0 | p <- takeWhile (\p -> p^2 <= 3) (2 : filter prime [3..])]
= 
and [rem 3 p > 0 | p <- takeWhile (<= 3) (4 : 
                                      map (\p -> p^2) (filter prime [3..]))]
= 
and [rem 3 p > 0 | p <- []]
=
and []
=
True
之后,我们可以在GHCi提示下进行检查

> :sprint primes
2 : 3 : _

(要使上述功能发挥作用,您需要从
prime
函数中提取
primes
,并使其本身成为顶级实体)。

请将代码作为文本而不是屏幕截图发布。它使阅读、本地测试和搜索更加容易。你认为逻辑是什么circular@Carl看我的编辑。哈斯克尔很懒;跟踪对
prime 2
的调用,注意在对
ldpf
的调用中实际上从未使用过
ps
。这意味着对
prime
的递归调用在你真正需要它之前是不会被执行的。这是一个太复杂的函数,无法考虑,请先尝试使用此斐波那契序列实现:
fibs=0:1:zipWith(+)fibs(tail fibs)
。请注意,它会生成一个无限列表。请将代码作为文本而不是屏幕截图发布。它使阅读、本地测试和搜索更加容易。你认为逻辑是什么circular@Carl看我的编辑。哈斯克尔很懒;跟踪对
prime 2
的调用,注意在对
ldpf
的调用中实际上从未使用过
ps
。这意味着对
prime
的递归调用在你真正需要它之前是不会被执行的。这是一个太复杂的函数,无法考虑,请先尝试使用此斐波那契序列实现:
fibs=0:1:zipWith(+)fibs(tail fibs)
。请注意,它会生成一个无限列表。cf,和。参见,和。