PasteRack.org
Paste # 41893
2018-10-11 10:36:08

Fork as a new paste.

Paste viewed 3846 times.


Embed:

Y combinator

  1. #lang racket/base
  2. ;; Y combinator / Normal Order
  3. (define (Yₙ    f ) (U (comp      f  U)))
  4. ;; Y combinator / Applicative Order
  5. (define (Yₐ    f ) (U (comp/eta  f  U)))
  6. ;; Polyvaradic Y Combinator / Normal Order
  7. (define (Yₙ* . f*) (U (mcomp     f* U)))
  8. ;; Polyvaradic Y Combinator / Applicative Order
  9. (define (Yₐ* . f*) (U (mcomp/eta f* U)))
  10.  
  11. ;; U Combinator. Matt Might is the only person I know of who calls it this.
  12. (define (U u)(u u))
  13. ;; η equivalent wrapper. ((eta: f ...) x ...) = ((f ...) x ...)
  14. (define-syntax-rule (eta: body ...)
  15.   (λ x* (apply (body ...) x*)))
  16.  
  17. ;;; Composition Variants
  18. (define ((comp     f g) u)(     f (g u)))
  19. (define ((comp/eta f g) u)(eta: f (g u)))
  20. ;; ((mcomp (list f ...) g) u) -> (list (apply f (g u)) ...)
  21. (define ((mcomp     f* g) u)
  22.   (map (λ(f)(     apply f (g u))) f*))
  23. (define ((mcomp/eta f* g) u)
  24.   (map (λ(f)(eta: apply f (g u))) f*))
  25.  
  26.  
  27. ;;; Examples
  28. (define-syntax-rule (rec (f x ...) body ...)
  29.   (Yₐ (λ(f)(λ(x ...) body ...))))
  30. (define-syntax-rule (rec* [(f x ...) body ...] ...)
  31.   (apply values (Yₐ* (λ(f ...)(λ(x ...) body ...)) ...)))
  32.  
  33. (define fib
  34.   (rec (f x)(if (< x 2) x (+ (f (- x 1))
  35.                              (f (- x 2))))))
  36.  
  37. (define-values (even? odd?)
  38.   (rec* [(even? n) (if (= n 0) #t (odd?  (sub1 n)))]
  39.         [(odd?  n) (if (= n 0) #f (even? (sub1 n)))]))
  40.  
  41. (let ([lst '(1 2 3 4 5 6 7 8 9 10)])
  42.   (and (equal? (map fib   lst) '(1 1 2 3 5 8 13 21 34 55))
  43.        (equal? (map even? lst) '(#f #t #f #t #f #t #f #t #f #t))
  44.        (equal? (map odd?  lst) '(#t #f #t #f #t #f #t #f #t #f))))

=>

#t