重複する要素を削除する uniq。ソートされているのが前提。
(define uniq
(lambda (lis)
(let loop ((e (car lis)) (l (cdr lis)))
(cond
((null? l) (list e))
((eq? e (car l)) (loop e (cdr l)))
(else (cons e (loop (car l) (cdr l))))))))
(print (uniq '(1 1 1 2 3 3)))
takatoh@nightschool $ gosh uniq.scm
(1 2 3)
リストのリストを引数にとって、car がユニークになるような手続き。
(define uniq-car
(lambda (lis)
(let loop ((e (car lis)) (l (cdr lis)))
(cond
((null? l) (list e))
((eq? (car e) (caar l)) (loop e (cdr l)))
(else (cons e (loop (car l) (cdr l))))))))
(print (uniq-car '((1 1) (1 2) (2 1) (2 2) (2 3) (3 1))))
takatoh@nightschool $ gosh uniq-car.scm
((1 1) (2 1) (3 1))
もう少し進んで、比較する方法を引数で渡せるようにしてみる。
(define uniq-in
(lambda (proc lis)
(let loop ((e (car lis)) (l (cdr lis)))
(cond
((null? l) (list e))
((eq? (proc e) (proc (car l))) (loop e (cdr l)))
(else (cons e (loop (car l) (cdr l))))))))
(print (uniq-in car '((1 1) (1 2) (2 1) (2 2) (2 3) (3 1))))
(print (uniq-in cadr '((1 1) (2 1) (3 1) (1 2) (2 2) (1 3))))
takatoh@nightschool $ gosh uniq-in.scm
((1 1) (2 1) (3 1))
((1 1) (1 2) (1 3))