#lang racket

(define (nat$ n)
  (cons n
        (lambda () (nat$ (add1 n)))))

;(car ((cdr (nat$ 0))))

(define (take$ $ n)
  (match $
         ['() '()]
         [whatever #:when (zero? n)
          '()]
         [`(,a . ,d) #:when (procedure? d)
          (cons a
                (take$ (d)
                       (sub1 n)))]
         [`(,a . ,d)
          (cons a
                (take$ d
                       (sub1 n)))]
         ))

(define (take$-b $ n)
  (match $
         ['() '()]
         [whatever #:when (and n (zero? n))
          '()]
         [`(,a . ,d) #:when (and n (procedure? d))
          (cons a
                (take$-b (d)
                       (and n (sub1 n))))]
         [`(,a . ,d)
          (cons a
                (take$-b d
                       (and n (sub1 n))))]
         ))

(take$ (nat$ 0) 5)
(take$ '(1 2 3 4 5) -1)
(take$-b '(1 2 3 4 5) #f)