ANSI Common Lisp入門? lispの世界へようこそ 練習問題2

(a b c)を返すcons式を3通り示せ。

これは(a b c)を渡したときに(a b c)を返す3通りのcons式を返す関数を定義しろという問題ですね。分かります><

(use util.match)
(define (cons: x y) `(cons ,x ,y))
(define (f xs)
  (match xs
    [() '()]
    [(x . xr)
     (cons (cons: x xr) 
	   (map (cute cons: x <>) (f xr)))]))

回答

(for-each print (f '(a b c)))
;; (cons a (b c))
;; (cons a (cons b (c)))
;; (cons a (cons b (cons c ())))

(a (b (c)) d)などを渡した時にはどうすればいいんでしょうか?><
ついでなので対応しておきましょう。

(use srfi-1)
(use util.match)

(define (cons: x y)  `(cons ,x ,y))
(define (f xs)
  (match xs
    [() '()]
    [(x . xr)
     (if (pair? x)
	 (let ((x* (cons x (f x))) (xr* (cons xr (f xr))))
	   (append-map (lambda (x) (map (cute cons: x <>) xr*)) x*))
	 (cons (cons: x xr) 
	       (map (cute cons: x <>) (f xr))))]))

;;
(for-each print (f '(a (b (c)) d)))
;; (cons a ((b (c)) d))
;; (cons a (cons (b (c)) (d)))
;; (cons a (cons (b (c)) (cons d ())))
;; (cons a (cons (cons b ((c))) (d)))
;; (cons a (cons (cons b ((c))) (cons d ())))
;; (cons a (cons (cons b (cons (c) ())) (d)))
;; (cons a (cons (cons b (cons (c) ())) (cons d ())))
;; (cons a (cons (cons b (cons (cons c ()) ())) (d)))
;; (cons a (cons (cons b (cons (cons c ()) ())) (cons d ())))