Schemeでuniq -- 隣り同士で重複してる要素を消す

30分プログラム、その625。隣り同士で重複してる要素を消すほうのuniqを作ってみる。

リスト中の全重複を消す関数もuniqとか呼ぶけど今回作ったのは、隣り同士の重複を消すだけのやつ。全重複を消すほうのやつは昔やったからね。
http://d.hatena.ne.jp/mzp/20070713/uniq

使い方

gosh> (uniq '(1 1 2 2 1))
(1 2 1)

;; 比較関数も渡せる
gosh> (uniq '((1 2) (1 3) (2 1) (1 1)) (lambda (x y) (eq? (car x) (car y))))
((1 2) (2 1) (1 1))
gosh>

ソースコード

#! /opt/local/bin/gosh
;; -*- mode:scheme; coding:utf-8 -*-
;;
;; uniq.scm -
;;
;; Copyright(C) 2009 by mzp
;; Author: MIZUNO Hiroki / mzpppp at gmail dot com
;; http://howdyworld.org
;;
;; Timestamp: 2009/07/22 21:36:58
;;
;; This program is free software; you can redistribute it and/or
;; modify it under MIT Lincence.
;;
(use util.match)
(define (uniq xs . arg)
  (let-optionals* arg ([cmp? eq?])
     (match xs
        [(or () (_)) xs]
	[(x y . xs) (if (cmp? x y)
			(uniq (cons x xs))
			(cons x
			      (uniq (cons y xs))))])))