将Y-Combinator应用于Clojure中带有两个参数的递归函数?

时间:2010-08-14 11:30:01

标签: recursion clojure lisp y-combinator

在Clojure中为单个参数函数(如factorial或fibonacci)执行Y-Combinator已有详细记录: http://rosettacode.org/wiki/Y_combinator#Clojure

我的问题是 - 你怎么做两个参数函数,例如这个getter?

(这里假设我想以递归的方式解决这个问题,这个非惯用的clojure代码是故意出于另一个原因)

[非y-combinator版本]

(defn get_ [n lat]
    (cond
      (empty? lat) ()
        (= 0 (- n 1)) (first lat)
        true (get_ (- n 1) (rest lat))))

(get_ 3 '(a b c d e f g h i j))

2 个答案:

答案 0 :(得分:4)

由于argsapply'd,因此args的数量不会发生任何变化。您只需要更改get_

的结构
(defn get_ [f]
  (fn [n lat]
    (cond
      (empty? lat) ()
      (= 1 n) (first lat)
      :else (f (dec n) (next lat)))))

(defn Y [f]
  ((fn [x] (x x))
   (fn [x]
     (f (fn [& args]
          (apply (x x) args))))))
user=> ((Y getf) 3 '(a b c d e f g h i j))
c

答案 1 :(得分:2)

这很直接。

说你有一个功能H:

(def H
  (fn [x] 
        (fn [x y]
              (stuff happens))))

然后你应用相同的'Y-Combinator:

((Y H) 4 5)

45是您要传递给H的参数。

组合子基本上是“处理”H中的顶级函数,而不是那些正在努力工作的人(这里有arity 2的人)。