ライブラリのサポートがなければ、独自のBoolean Reader Monadをロールアウトできます。
これは機能的で、純粋で、構成可能です。
ブールリーダー
case class BoolConf[A](run: Boolean => A) {
def apply(b: Boolean) = run(b)
def map[B](f: A => B): BoolConf[B] = BoolConf(b => f(run(b)))
def flatMap[B](f: A => BoolConf[B]): BoolConf[B] = BoolConf(b => f(run(b))(b))
}
Boolean => A
ここでは、モナド構成を可能にする a のラッパーを作成しました。これは、おそらくすでにscalazなどのライブラリに実装されています。
この場合、私たちはメソッドにのみ関心がありrun
ますが、他の機会に関心を持つことができます。
構成されたフィルターと並べ替え
次に、フィルタと並べ替えチェックを次のようにラップします。Reader
val mFilter: Seq[SomeClass] => BoolConf[Seq[SomeClass]] = seq => BoolConf(if(_) seq.filter(...) else seq)
val mSort: Seq[SomeClass] => BoolConf[Seq[SomeClass]] = seq => BoolConf(if(_) seq.sortWith(...) else seq)
リフティング
ここで、これらの関数を構成するには、出力がもはや単純ではないため、関数の 1 つを持ち上げSeq
て関数内で動作させる必要があります。BoolConf
def lift2Bool[A, B]: (A => B) => (BoolConf[A] => BoolConf[B]) =
fun => cfg => BoolConf(bool => fun(cfg(bool)))
A => B
これで、任意の関数をから持ち上げられた関数に変換できるようになりましたBoolConf[A] => BoolConf[B]
作曲
これで、機能的に構成できます。
val filterAndSort = lift2Bool(mSort) compose mFilter
//or the equivalent
val filterAndSort = mFilter andThen lift2Bool(mSort)
//applies as in filterAndSort(<sequence>)(<do filter>)(<do sort>)
もっとあります
との一般的な「ビルダー」を作成することもできmFilter
ますmSort
val configFilter[SomeClass]: (SomeClass => Boolean) => Seq[MyClass] => BoolConf[Seq[SomeClass]] =
filterer => seq => BoolConf(if(_) seq.filter(filterer))
ソートに相当するものを自分で「ソート」できます
インスピレーションを与えてくれたRunarに感謝します