Spec の導入により、すべての関数に対して test.check ジェネレーターを作成しようとしています。これは単純なデータ構造では問題ありませんが、相互に依存する部分を持つデータ構造では困難になる傾向があります。つまり、ジェネレーター内で何らかの状態管理が必要になります。
Clojure の loop/recur または reduce に相当するジェネレーターを用意することは、すでに非常に役立ちます。これにより、1 つの反復で生成された値を、後続の反復でアクセスできる集計値に格納できます。
これが必要となる簡単な例の 1 つは、コレクションを正確に X 個のパーティションに分割するジェネレータを作成することです。各パーティションは 0 から Y 個の要素を持ち、要素は任意のパーティションにランダムに割り当てられます。
test.chuck
(のpartition
関数では、X または Y を指定できないことに注意してください)。コレクションをループしてこのジェネレーターを作成する場合、Y を超えないようにするために、前の反復中にいっぱいになったパーティションにアクセスする必要があります。
誰にもアイデアはありますか?私が見つけた部分的な解決策:
test.check
let
をbind
使用すると、値を生成して後でその値を再利用できますが、反復は許可されません。tuple
と関数を組み合わせて、以前に生成された値のコレクションを反復処理できますbind
が、これらの反復では、以前の反復中に生成された値にアクセスできません。(defn bind-each [k coll] (apply tcg/tuple (map (fn [x] (tcg/bind (tcg/return x) k)) coll))
アトム (または揮発性) を使用して、前の反復中に生成された値を保存およびアクセスできます。
reset!
これは機能しますが、特に、ジェネレーターが返される前にアトム/揮発性が必要なため、ジェネレーターの次の呼び出しでそれらの内容が再利用されるのを避けるために、Clojure とはまったく異なります。bind
ジェネレーターは、そのand関数によりモナドに似てreturn
います。これは、Cats などのモナド ライブラリーを State モナドと組み合わせて使用することを示唆しています。ただし、State モナドは Cats 2.0 で削除されました (Clojure に適していないと言われているため)。一方、私が知っている他のサポート ライブラリでは、Clojurescript が正式にサポートされていません。さらに、Clojure のモナド専門家の 1 人である Jim Duey は、自身のライブラリに State モナドを実装する際に、State モナドの使用は test.check の縮小と互換性がないと警告しているようです ( http://www.これは、 test.checkを使用するメリットを大幅に減らします。