생성일: 2019년 12월 27일
수정일: 2023년 08월 20일
수정일: 2023년 08월 20일
4clojure - Reimplement Trampoline (78)
문제
(= (letfn [(triple [x] #(sub-two (* 3 x)))
(sub-two [x] #(stop?(- x 2)))
(stop? [x] (if (> x 50) x #(triple x)))]
(__ triple 2))
82)
(= (letfn [(my-even? [x] (if (zero? x) true #(my-odd? (dec x))))
(my-odd? [x] (if (zero? x) false #(my-even? (dec x))))]
(map (partial __ my-even?) (range 6)))
[true false true false true false])
제한 : trampoline
풀이
(fn [f & args] (loop [f (apply f args)] (if (fn? f) (recur (f)) f)))
풀이과정
그냥 함수 호출 하는 방법으로 해봤다
(letfn [(triple [x] #(sub-two (* 3 x)))
(sub-two [x] #(stop?(- x 2)))
(stop? [x] (if (> x 50) x #(triple x)))]
((fn [f x] (f x)) triple 2))
;; #object[user$eval136$triple__137$fn__138 0x2f05be7f "user$eval136$triple__137$fn__138@2f05be7f"]
실행할 준비가 되는 상태로만 되는 것 같다.
함수의 실행에 대한 문제가 아니라 뭔가 다른 방식에 대한 문제 인 것 같다. 간단하게 함수를 호출을 해도 그냥 정의만 되어 버린다.
(letfn [(triple [x] #(sub-two (* 3 x)))
(sub-two [x] #(stop?(- x 2)))
(stop? [x] (if (> x 50) x #(triple x)))]
(triple 2))
;; #object[user$eval152$triple__153$fn__154 0x68ad99fe "user$eval152$triple__153$fn__154@68ad99fe"]
뭔가 내가 모르는 다른 방식이 더 있는 것 같다. 그걸 어떻게 찾아야 할지 고민이 된다. 왜 실행이 되지 않는지 라는 생각이 자꾸 들긴 한다.
생각하다가 도저히 답이 안나와서 다른 사람들은 어떻게 풀었는지 참고를 하기로 했다. 왜 위에 함수가 실행이 되지 않는지도 이해가 가지 않아서 정말 모르는 방법인거 같아 참고한다.
(fn [f & args] (loop [f (apply f args)] (if (fn? f) (recur (f)) f)))
문제를 잘못 이해하고 있었다 함수 내부에서 익명 함수를 사용한 것이 아니라 함수를 반환하고 있었다 그래서 위 해결 방법에서 fn?으로 반환된 결과가 함수인지를 판단하고 그 함수를 실행 시켜서 하고 있었던 것이다 결과적으로 (fn)과 같은 동작의 샆 태그인데 왜 저렇게 동작이 되는 것인지 계속 고민을 하고 있었던 것이다 위 1번테스트를 풀이 한다면 다음과 같은 흐름으로 실행이 된다
(triple 2)
;; (apply triple '(2))
;; (#(sub-two 6))
;; (apply #(stop? 4) '())
;; (#(triple 4))
;; (apply #(sub-two 12) '())
;; (#(stop? 10))
;; (apply #(triple 10) '())
;; (#(sub-two 30))
;; (apply #(stop? 28) '())
;; (#(triple 28))
;; (apply #(sub-two 84) '())
;; (#(stop? 82))
;; 82