【问题标题】:Non tail-recursive anonymous functions in ClojureClojure 中的非尾递归匿名函数
【发布时间】:2011-08-03 08:31:17
【问题描述】:

如何在 Clojure 中创建一个非尾递归的递归匿名函数?

以下显然不起作用,因为recur 仅适用于尾递归函数。我也不愿意拖入 y-combinator..

((fn [n] (if (= 1 n) 1 (* n (recur (dec n))))) 5)

【问题讨论】:

  • “给它一个名字”?他们叫我匿名先生... :P~

标签: recursion lambda clojure


【解决方案1】:

可以通过在 fn 和 arglist 之间指定函数来为函数指定一个名称来引用自身:

user> ((fn ! [n] (if (= 1 n) 1 (* n (! (dec n))))) 5)
120

【讨论】:

  • 为匿名函数命名好! +1
  • 称它为 ! 似乎与惯例背道而驰,因为它不会改变任何东西。
  • 他定义的函数是阶乘函数。我可以称它为fact,但数学家称它为!,而且我们正在使用一种允许我们称其为相同的语言。当每个人都知道 5 时,写更长的东西似乎很愚蠢!是 120。
【解决方案2】:

这是一种保持匿名的方式,主要是:

(((fn [!] (fn [n] (if (= 1 n) 1 (* n ((! !) (dec n)))))) 
  (fn [!] (fn [n] (if (= 1 n) 1 (* n ((! !) (dec n))))))) 
 5)

它不完全是 Y 组合器,但它确实包含相同的自我应用程序,允许 Y 做它的事情。通过在需要时将整个函数复制到! 范围内,您可以随时制作另一个副本。

【讨论】:

  • 您可以删除其中的一些重复项: (((fn [!] (fn [n] ((! !) n))) (fn [!] (fn [n] (if (= 1 n) 1 (* n ((! !) (dec n)))))) 5) 这显然不是这样做的方法(鉴于 Clojure 可以命名 fns,但我仍然喜欢。:)
猜你喜欢
  • 2019-05-19
  • 2022-06-20
  • 2013-05-15
  • 2011-07-17
  • 2011-10-24
  • 2015-11-21
  • 2011-01-29
  • 2011-04-22
  • 2020-09-24
相关资源
最近更新 更多