http://quasiquote.org/log2/ にて細々とやってます。
とりあえず足跡ぺたり。
Gaucheから共有ライブラリを簡単に呼出す試み。Chickenのlazy-ffiにならいました。
Gauche:FFIにあるようにScmForeignPointerが使えるようになれば、 もうちょっとスマートなものになるのかな?
Erlangのlists:subtract/2('--'演算子)みたいなのは無いのかなあ。探すのもめんどうだなあ。 ということで、 とりあえずベタベタなコードを書いてみた。
(define (subtract h . t)
(define (delete-first x li)
(let loop ((li li)
(buf '()))
(if (null? li)
(reverse buf)
(if (equal? (car li) x)
(append (reverse buf) (cdr li))
(loop (cdr li) (cons (car li) buf))))))
(define (subtract2 x y)
(let loop ((x x)
(y y))
(if (null? y)
x
(loop (delete-first (car y) x) (cdr y)))))
(let loop ((t t)
(buf h))
(if (null? t)
buf
(loop (cdr t) (subtract2 buf (car t))))))
使用例。こんなのが、
perms([]) -> [[]];
perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].
% test
lists:foreach(fun (X) -> io:fwrite("~s ", [X]) end, perms:perms("test")).
こんなのに。
(use srfi-42)
(define (perms l)
(if (null? l)
'(())
(list-ec (: h l) (: t (perms (subtract l (list h)))) (cons h t))))
;; test
(map list->string (perms (string->list "test")))
(use srfi-1)
(define (delete-first x ys)
(receive (h t) (break (cut equal? x <>) ys)
(if (null? t)
h
(append! h (cdr t)))))
(define (subtract xs . yss)
(fold delete-first xs (concatenate! yss)))