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

日を跨いだのでエントリを分けます。煮つまったので氷を買うついでに散歩。散歩しつつ、app-term なナニは分けちゃえ、な思いつきを基に以下がでっち上がりました。

(define app-parse
  (lambda (datum)
    (if (null? datum)
	'()
	(cons (parse (car datum))
	      (app-parse (cdr datum))))))

(define parse
  (lambda (datum)
    (cond ((symbol? datum) (var-term datum))
	  ((constant? datum) (constant-term datum))
	  ((pair? datum)
	   (app-term (app-parse datum)))
	  (else
	   (eopl:error 'parse
		       "Invalid syntex ~s" datum)))))

list に惑わされたりなんかしましたが、以下の試験にパスしてます。

(use gauche.test)

(add-load-path ".")
(load "parse")

(test-start "parse")
(test-section "parse")
(test* "(parse 'x)"
       '(var-term x)
       (parse 'x))
(test* "(parse #t)"
       '(constant-term #t)
       (parse #t))
(test* "(parse #f)"
       '(constant-term #f)
       (parse #f))
(test* "(parse 0)"
       '(constant-term 0)
       (parse 0))
(test* "(parse \"a\")"
       '(constant-term "a")
       (parse "a"))

(test* "(parse '(\"cons\" w x))"
       '(app-term ((constant-term "cons")
		   (var-term w)
		   (var-term x)))
       (parse '("cons" w x)))
       
(test* "(parse '(\"append\" (\"cons\" w x) y (\"cons\" w z)))"
       '(app-term
	 ((constant-term "append")
	  (app-term
	   ((constant-term "cons") (var-term w) (var-term x)))
	  (var-term y)
	  (app-term
	   ((constant-term "cons") (var-term w) (var-term z)))))
       (parse '("append" ("cons" w x) y ("cons" w z))))

(test-end)

いいのかなぁ。とりあえず 0100 過ぎてるんですが unparse に着手するかどうか悩ましい。

unparse

簡単なナニの試験を書いてみた。

(use gauche.test)

(add-load-path ".")
(load "unparse")

(test-start "unparse")
(test-section "unparse")
(test* "(unparse '(var-term x))"
       'x
       (unparse '(var-term x)))
(test* "(unparse '(constant-term #t))"
       #t
       (unparse (constant-term #t)))
(test* "(unparse '(constant-term #f))"
       #f
       (unparse (constant-term #f)))
(test* "(unparse '(constant-term '()))"
       '()
       (unparse (constant-term ())))
(test* "(unparse '(constant-term 0))"
       0
       (unparse (constant-term 0)))
(test* "(unparse '(constant-term \"a\"))"
       "a"
       (unparse (constant-term "a")))


(test-end)

app-term は今のところ略。原型が以下。

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

(define unparse
  (lambda (l)
    (cases term l
	   (var-term (id)
		     )
	   (constant-term (datum)
			  )
	   (app-term (terms)
		     )
	   )))

よく考えたら var-item とか constant-item とかってそのまんまじゃん。

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

(define unparse
  (lambda (l)
    (cases term l
	   (var-term (id) id)
	   (constant-term (datum) datum)
	   (app-term (terms)
		     )
	   )))

試験はパス。

Testing unparse ===============================================================
<unparse>----------------------------------------------------------------------
test (unparse '(var-term x)), expects x ==> ok
test (unparse '(constant-term #t)), expects #t ==> ok
test (unparse '(constant-term #f)), expects #f ==> ok
test (unparse '(constant-term '())), expects () ==> ok
test (unparse '(constant-term 0)), expects 0 ==> ok
test (unparse '(constant-term "a")), expects "a" ==> ok

このあたりは楽勝なんですが次がねぇ。
で、でっち上げたのが以下な試験と

(test* "(unparse '(app-term ((constant-term \"cons\") (var-term a) (var-term b))))"
       '("cons" a b)
       (unparse (app-term (list (constant-term "cons") (var-term 'a) (var-term 'b)))))

以下な手続き。

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

(define unparse
  (lambda (l)
    (cases term l
	   (var-term (id) id)
	   (constant-term (datum) datum)
	   (app-term (terms)
		     (let f ((rslt '()) (list terms))
		       (cond ((null? list) rslt)
			     (else
			      (f (append rslt (list (unparse (car list))))
				 (cdr list)))))))))

何故に f の引数を list にしたのだと小一時間 (あるいは二時間)。変数の名前がダメ、って事に気づいて今に至ってます。
修正後のソレが以下。

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

(define unparse
  (lambda (exp)
    (cases term exp
	   (var-term (id) id)
	   (constant-term (datum) datum)
	   (app-term (terms)
		     (let f ((rslt '()) (l terms))
		       (cond ((null? l) rslt)
			     (else
			      (f (append rslt (list (unparse (car l))))
				 (cdr l)))))))))

上記の試験にはパスしてます。気が狂うかと思った。変数名の付けかたには気をつけねば、と思いつつも同じコトを繰り返しております。
もう少し複雑なナニの試験は明日。