Given that there are an arbitrary amount of natural numbers, a well-formed self-referential data definition should be used to define a Natural
(data type representing natural numbers).
Here’s a function template for naturals
(define (fn-for-natural n)
(cond [(zero? n) (...)]
[else
(... n ; template rules don't use this but this format seems to reappear
; a lot so we'll use it
(fn-for-natural (sub1 n)))]))
Example:
Natural
number n
and produces the sum of all
the naturals in [0, n]
.Natural
number n
and produces a list of all
the naturals of the form (cons n (cons n-1 ... empty)
) not including 0
.Here’s the Racket file for this example:
;; ================
;; Data definitions
;; ================
;; Natural is one of:
;; - 0
;; - (add1 Natural)
;; interp. a natural number
(define N0 0) ;0
(define N1 (add1 N0)) ;1
(define N2 (add1 N1)) ;2
(define (fn-for-natural n)
(cond [(zero? n) (...)]
[else
(... n ; template rules don't use this but this format seems to reappear
; a lot so we'll use it
(fn-for-natural (sub1 n)))]))
;; Template rules used:
;; - one-of: two cases
;; - atomic distinct: 0
;; - compound: (add1 Natural)
;; - self-reference: (sub1 n) is Natural
;; =========
;; Functions
;; =========
;; (A)
;; Natural -> Natural
;; takes a Natural n and produces the sum of all naturals in [0,n]
;; (define (sum n) 0) ; stub
(check-expect (sum 0) 0) ; base case
(check-expect (sum 1) 1)
(check-expect (sum 3) (+ 3 2 1 0))
(check-expect (sum 5) (+ 5 4 3 2 1 0))
(define (sum n)
(cond [(zero? n) 0] ; base case
[else
(+ n
(sum (sub1 n)))])) ; recursive case
;; (B)
;; Natural -> ListOfNatural
;; takes a Natural n and returns a list of all the naturals in [1,n]
;; (define (to-list n) empty) ;; stub
(check-expect (to-list 0) empty) ; base case
(check-expect (to-list 1)
(cons 1 empty))
(check-expect (to-list 3)
(cons 3
(cons 2
(cons 1
empty))))
(define (to-list n)
(cond [(zero? n) empty] ; base case
[else
(cons n
(to-list (sub1 n)))])) ; recursive case