Magicode logo
Magicode
0
2 min read

ファイルを読み込むためにunfoldぽい関数を作ってみました.

https://cdn.apollon.ai/media/notebox/blob_WppV1Vj

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)))))

使ってみました.

ディレクトリをみる関数です
(fn dirlookup [dir depth]
   "file only, depth 1
    find . -maxdepth 1 -type f"
   (local p (io.popen (.. "find \"" dir  "\" -maxdepth " depth " -type f")))
   (unfold-iter (p.lines p) p (lambda [x] (io.close x))))
コマンドを実行する関数です.
(fn execute-cmd [cmd]
   "Execute command and return output as list."
   (local p (io.popen cmd))
   (unfold-iter (p.lines p) p (lambda [x] (io.close x))))

Discussion

コメントにはログインが必要です。