EoPL reading (100) 2.2 An Abstraction for Inductive Data Type

もう 100 だ (何
それは良いとして 2.2 ラストの Exercise 2.13 着手。

Exercise 2.13

とりあえず、以下が示されてます。

(define-datatype term term?
  (var-term
   (id symbol?))
  (constant-term
   (datum constant?))
  (app-term
   (terms (list-of term?))))

list-of って何だったか、と言いつつ以下を追加。

(define constant?
  (lambda (datum)
    (or (string? datum)
	(number? datum)
	(boolean? datum)
	(null? datum))))

(define list-of
  (lambda (pred)
    (lambda (val)
      (or (null? val)
	  (and (pair? val)
	       (pred (car val))
	       ((list-of pred) (cdr val)))))))

で、試験が以下。多分モレがあるはず。

(use gauche.test)

(add-load-path ".")
(load "define-datatype")
(load "term")

(test-start "term")
(test-section "constant?")
(test* "(constant? \"a\")"
       #t
       (constant? "a"))
(test* "(constant? 1)"
       #t
       (constant? 1))
(test* "(constant? #t)"
       #t
       (constant? #t))
(test* "(constant? #f)"
       #t
       (constant? #f))
(test* "(constant? '())"
       #t
       (constant? '()))
(test* "(constant? 'a)"
       #f
       (constant? 'a))
(test* "(constant? '(1 2))"
       #f
       (constant? '(1 2)))
(test* "(constant? '(lambda (x) x))"
       #f
       (constant? '(lambda (x) x)))

(test-section "term")
(test* "(term? '(var-term s))"
       #t
       (term? '(var-term s)))
(test* "(term? '(constant-term \"a\"))"
       #t
       (term? '(constant-term "a")))
(test* "(term? '(constant-term 1))"
       #t
       (term? '(constant-term 1)))
(test* "(term? '(constant-term #t))"
       #t
       (term? '(constant-term #t)))
(test* "(term? '(constant-term #f))"
       #t
       (term? '(constant-term #f)))
(test* "(term? '(constant-term '()))"
       #t
       (term? '(constant-term '())))
(test* "(term? '(app-term ((constant-term \"cons\"))"
       #t
       (term?  '(app-term ((constant-term "cons")))))
(test* "(term? '(app-term ((var-term 'a) (var-term 'b))))"
       #t
       (term?  '(app-term ((var-term 'a) (var-term 'b)))))

(test-end)

で、次は parse だな、と言いつつ検討してるんですが、ハマり中。