Sinh vật bạn đang tìm kiếm là Y * bộ kết hợp.
Căn cứ vào this page by oleg-at-okmij.org tôi chuyển các Y * để Clojure:
(defn Y* [& fs]
(map (fn [f] (f))
((fn [x] (x x))
(fn [p]
(map
(fn [f]
(fn []
(apply f
(map
(fn [ff]
(fn [& y] (apply (ff) y)))
(p p)))))
fs)))))
Các ví dụ điển hình của hàm đệ quy lẫn nhau là chẵn/lẻ vì vậy đây là ví dụ:
(let
[[even? odd?]
(Y*
(fn [e o]
(fn [n]
(or (= 0 n) (o (dec n)))))
(fn [e o]
(fn [n]
(and (not= 0 n) (e (dec n)))))
)
]
(do
(assert (even? 14))
(assert (odd? 333))
))
Bạn có thể dễ dàng thổi các ngăn xếp với các chức năng này nếu bạn sử dụng các đối số đủ lớn, do đó, đây là phiên bản trampolined của nó cho ví dụ đầy đủ mà không tiêu thụ ngăn xếp ở tất cả:
(let
[[even? odd?]
(Y*
(fn [e o]
(fn [n]
(or (= 0 n) #(o (dec n)))))
(fn [e o]
(fn [n]
(and (not= 0 n) #(e (dec n)))))
)
]
(do
(assert (trampoline even? 144444))
(assert (trampoline odd? 333333))
))
Các Y * combinator là rất hữu ích cho việc xác định các định nghĩa đệ quy lẫn nhau về parsers monadic, trong đó tôi sẽ viết blog sớm trên lambder.com, chơ;)
- Lambder
haskell! = Lambda-calculus – eschulte