gpt4 book ai didi

function - Clojure 具有多重性

转载 作者:行者123 更新时间:2023-12-04 04:17:56 24 4
gpt4 key购买 nike

我可能有点超前了,我在学习 Clojure 的第一天几乎没有接触过函数,但我认为我会雄心勃勃,并制作一个递归函数来将浮点值转换为三元值。如果我按名称而不是使用 recur 调用函数,效果会很好。我知道问题是我只是 recur 函数的 1-arity 版本,是否有标准方法来处理 multi-arity 函数中的递归?我正在阅读的书似乎没有涵盖它。

(defn float-to-ternary
([x k s]
(def a (int x))
(def r (- x a))
(def carry-string (str s (. Integer toString a 3)))
(cond
(== r 0) carry-string
(> k 20) carry-string
:default (recur (* 3 r) (inc k) carry-string)
)
)
([x]
(def a (int x))
(def r (- x a))
(def carry-string (str (. Integer toString a 3) "."))
(cond
(== r 0) (str (. Integer toString a 3))
:default (recur (* 3 r) 1 carry-string)
)
)
)

最佳答案

如果你想“recur 到一个不同的 arity”,只需显式调用函数而不是使用 recur:

(defn float-to-ternary
([x k s]
(def a (int x))
(def r (- x a))
(def carry-string (str s (. Integer toString a 3)))
(cond
(== r 0) carry-string
(> k 20) carry-string
:default (recur (* 3 r) (inc k) carry-string)))

([x]
(def a (int x))
(def r (- x a))
(def carry-string (str (. Integer toString a 3) "."))
(cond
(== r 0) (str (. Integer toString a 3))
:default (float-to-ternary (* 3 r) 1 carry-string))))

这是安全的。当您不使用 recur 时,您“花费”了一个堆栈帧,但其余递归使用 recur,所以没问题。


不过我也有一些强制性的建议:

  • 不要在函数内部使用 def 除非你真的有很好的理由。 def 创建函数返回时不会超出范围的全局变量!

  • 您没有必要使用 cond

    • 在第一个主体中,您希望为前两个条件返回 carry-string。您可以只设置一个条件,用 or 连接这两个条件,这样您就可以简单地使用 if

    • 由于第二次使用只有两个结果,if 再次更有意义。

考虑到这一点,您的代码看起来更像是:

(defn float-to-ternary
([x k s]
(let [a (int x)
r (- x a)
carry-string (str s (. Integer toString a 3))]
(if (or (> k 20) (== r 0))
carry-string
(recur (* 3 r) (inc k) carry-string))))

([x]
(let [a (int x)
r (- x a)
carry-string (str (. Integer toString a 3) ".")]
(if (== r 0)
(str (. Integer toString a 3))
(float-to-ternary (* 3 r) 1 carry-string)))))

关于function - Clojure 具有多重性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49546574/

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