Unfoldとは
リストが作れる関数です.
(fn unfold [condition func iterate-update seed]
"1. apply `func` to `seed`.
2. insert return value of `func` into list.
3. update `seed` with `iterate-update`
4. ..."
(if (condition seed)
[]
(pull (func seed) (unfold condition func iterate-update (iterate-update seed)))))
関数pullは以下で説明します.
まずcarを作りました.
car, cdr, consがないので可変長引数で作ってみました.組み込み関数(table.insert等)を使えばもっと速いと思いますが,きれいにかけて嬉しかったです.
(fn car [x ...]
x)
(fn cdr [x ...]
[...])
(fn cons [x ...]
[x ...])
(fn first [lst]
"use as car"
(car (unpack lst)))
(fn rest [lst]
"use as cdr"
(cdr (unpack lst)))
(fn pull [x xs]
"use as cons"
(cons x (unpack xs)))
pullという名前付けは我ながらよいと思いました.
できたもの
先にイテレータを消費してnilだったらfinishを実行します.
(fn unfold-iter [seed object finish]
" unfold the iterator
example:
(local p (io.popen ))
(unfold-iter (p.lines p) p (lambda [x] (io.close x))))"
(let [v (seed)]
(if (= nil v)
(do
(finish object)
[])
(pull v (unfold-iter seed object finish)))))