这是Haskell中的函数吗?如果是,我们应该如何阅读?
在Doets等人的Haskell Road to Logic,Math and Programming一书第103页中,给出了这是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
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
函数使用listprimes
,但要生成该列表,我们还使用函数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,和。参见,和。