如果没有库支持,您可以推出自己的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 做了一个包装器,它允许单子组合,并且它可能已经在某些库中实现,例如 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)
提升
现在,组合这些函数,因为输出不再是简单的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 的启发