Clojure中的相互递归定义 [英] Mutually recursive definitions in Clojure

查看:104
本文介绍了Clojure中的相互递归定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在Clojure中进行相互递归的定义?

How do I do mutually recursive definitions in Clojure?

这是Scala中的代码,用于查找使用递归定义的素数:

Here is a code in Scala to find prime numbers which uses recursive definitions:

val odds: Stream[Int] = cons(3, odds map { _ + 2 })
val primes: Stream[Int] = cons(2, odds filter isPrime)
def primeDivisors(n: Int) =
    primes takeWhile { _ <= Math.ceil(Math.sqrt(n))} filter { n % _ == 0 }
def isPrime(n: Int) = primeDivisors(n) isEmpty

primes take 10

我将此翻译为Clojure:

I translated this to Clojure:

(def odds (iterate #(+ % 2) 3))
(def primes (cons 2 (filter is-prime odds)))
(defn prime-divisors [n]
    (filter #(zero? (mod n %)) 
        (take-while #(<= % (Math/ceil (Math/sqrt n))) 
            primes)))
(defn is-prime [n] (empty? (prime-divisors n)))

(take 10 primes)

但是在Clojure REPL中一个接一个地写出定义

But writing the definitions in the Clojure REPL one by one gives

java.lang.Exception: Unable to resolve symbol: is-prime in this context (NO_SOURCE_FILE:8)

写完(def primes (cons 2 (filter is-prime odds)))之后.

是否可以在Clojure中进行相互递归的定义?

Is there a way to do mutually recursive definitions in Clojure?

推荐答案

Greg的答案是正确的.但是,您必须重新排列代码:(def odds ...) (declare primes) (defn prime-divisors ...) (defn prime? ...) (def primes ...).这应该可以解决问题.

Greg's answer is correct. However you have to rearrange your code: (def odds ...) (declare primes) (defn prime-divisors ...) (defn prime? ...) (def primes ...). This should do the trick.

问题在于,素数的定义不是函数.它会立即执行,因此尝试取消引用尚未绑定的prime? Var.因此,例外.重新安排时应注意这一点.

The problem is, that the definition of primes is not a function. It is executed immediately and hence tries to dereference the prime? Var which is not bound, yet. Hence the exception. Re-arranging should take care of that.

(免责声明:我没有检查代码是否可以重新安排.)

(Disclaimer: I haven't checked that the code works with the re-arrangement.)

我认为prime?已损坏. (prime? 2)应该给false,不是吗?

And I think prime? is broken. (prime? 2) should give false, no?

这篇关于Clojure中的相互递归定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆