Gauche:find系APIの整理
Shiro(2021/05/28 21:55:42 UTC): 「コレクションから条件に合う要素を見つける」という操作について、命名やインタフェースに若干混乱があるので整理
find系
pred :: element -> generalized-boolean
- 最初にtruthを返した
element
を返す - 辞書系のコレクションの場合、predはkeyとvalueを取る。見つかった場合には2値を返す。
- APIについては以下のバリエーション
:: pred, collection -> element
: 元祖find。みつからなかったら#f
を返す。欠点として、見つけたい要素が#f
である場合を扱えない。find
srfi-1, scheme.list ifind
srfi-116, scheme.ilist generator-find
srfi-158, scheme.generator lseq-find
srfi-127, scheme.lseq stream-find
util.stream (Gauche独自) :: pred, collection, (() -> element) -> element
: 見つからなかった時に呼び出すfailure thunkを取るもの。新しめのsrfiに多い。bag-find
srfi-113, scheme.set hashmap-find
srfi-146, scheme.mapping idequeue-find
srfi-134, scheme.idequeue (failureはoptional) iset-find
srfi-217 mapping-find
srfi-146, scheme.mapping set-find
srfi-113, scheme.set :: collection, pred, :optional (() -> element) -> element
: 述語とコレクションの順序が逆。これはGauche specificな次の手続きだけなので、0.9.11で上の2.に揃える。binary-heap-find
**data.heap :: collection, pred -> key, value, found?
:hashtable-find
srfi-126
hash-table-find
(Gauche, srfi-125)は下のany系になる。
汎用性を考えるなら「pred, collection, :optional failure -> element
」で統一するのが良さそう。3.は歴史的遺物だけど、互換性を残したまま引数は入れ替えられるので、2.に統一すべき。
collectionが順序つきの場合、「逆方向から探す」というバリエーションがあり得る。
:: pred, collection -> element
ifind-tail
srfi-116, scheme.ilist lseq-find-tail
srfi-127, scheme.lseq stream-find-tail
util.stream, Gauche独自 :: pred, collection, (() -> element) -> element
idequeue-find-right
srfi-134, scheme.idequeue (failureはoptional)
any系
pred :: element -> result
- 最初にpredがtruthを返した時の返り値をそのまま返す (要素の値ではなく)
- APIのバリエーション
:: pred, collection -> result
: 見つからなかった場合は#f
。char-set-any
srfi-14, scheme.charset generator-any
srfi-158, scheme.genrator lseq-any
srfi-127, scheme.lseq :: pred, collection, ... -> result
: collectionを複数取る。見つからなかった場合は#f
。any
srfi-1, scheme.list array-any
srfi-179 flexvector-any
srfi-214 iany
srfi-116, scheme.ilist idequeue-any
srfi-134, scheme.idequeue range-any
srfi-196 stream-any
util.stream, Gauche独自 vector-any
srfi-133, scheme.vector @vector-any
srfi-160, scheme.vector.@ :: pred, collection, :optional (() -> result) -> result
: failure thunkを取るhash-table-find
srfi-125, scheme.hash-table :: collection, pred, :optional (() -> result) -> result
: 2.のpredとcollectionが逆。これはGauche組み込みで後方互換性のため。だがhash-table-find
Gauche :: pred, collection, :optional start end -> result
: 見つからなかったら#f
。string-any
srfi-13 textual-any
srfi-135, scheme.text
any? 系
pred :: element -> generalized-boolean
- predがtruthを返したら直ちに
#t
を、そうでなければ#f
を返す。「見つかったものは何か」に関する情報は返せない。 - APIのバリエーション
:: pred, collection -> boolean
bag-any?
srfi-113, scheme.set enum-set-any?
srfi-209 hashmap-any?
srfi-146, scheme.mapping iset-any?
srfi-217 mapping-any?
srfi-146, scheme.mapping set-any?
srfi-113, scheme.set :: collection, start, end -> boolean
: ビットを扱うもの。predは自明なので取らない。bit-field-any?
srfi-151, scheme.bitwise bitvector-field-any?
srfi-178
seek系
find
、any
、またいくつかのsrfiにみられるsearch
系(predicateではなく探す要素を取り、結果に応じて呼ばれる継続手続きを取る)を統一的に実装するために、
Gaucheでgauche.dictionary
に実験的に入れてみたもの。まだundocumented。
- 0.9.10時点では以下のシグネチャ
*-seek :: collection, pred, success, failure
pred :: element -> result
success :: result, key, value -> *
failure :: () -> *
dictionary frameworkで使うなら、collectionが先に来る方が良い。
継続手続きに関しては、search
系がfailure, successの順なのでそれに合わせる方が良いか。0.9.11で変える。
Maybeモナド
- まだ実装はないが、srfi-189のmaybeを使うことで、見つからなかった場合と見つかった時に返す値を明確に区別できる
- find系とany系が考えられる。
Maybe find系
:: (element -> generalized-boolean), collection -> Maybe element
Maybe any系
:: (element -> Maybe result), collection -> Maybe result