我有两个谓词
interface Foo {}
interface Bar {}
declare const isFoo: (a:unknown):a is Foo
declare const isBar: (a:unknown):a is Bar
组合两个谓词以创建新谓词的功能方式是什么(为简单起见,我们假设它是a => isFoo(a) && isBar(a)
?
使用fp-ts
,我最初认为我可以fold(monoidAll)([isFoo, isBar])
,但fold
希望数组是布尔值,而不是评估为布尔值的函数。
这有效
import { monoid as M, function as F, apply as A, identity as I, reader as R } from 'fp-ts'
interface Foo{}
interface Bar{}
declare const isFoo:(a:unknown) => a is Foo
declare const isBar:(a:unknown) => a is Bar
const isFooAndBar = F.pipe(A.sequenceT(R.reader)(isFoo, isBar), R.map(M.fold(M.monoidAll)))
但是男孩,你好是令人费解的。我以为可能有另一种方式。我最终编写了自己的幺半群,它接受两个谓词并将它们组合起来,称之为monoidPredicateAll
:
const monoidPredicateAll:M.Monoid<Predicate<unknown>> = {
empty: ()=>true,
concat: (x,y) => _ => x(_) && y(_)
}
是否有一种结合两个谓词的规范 FP 方式?我知道我可以做类似的事情
xs.filter(x => isFoo(x) && isBar(x))
但是它可能会因为更多的谓词而变得复杂,并且重新使用一个幺半群使得我不太可能像isFoo(x) || isBar(x) && isBaz(x)
我的意思一样做错字&&
(这就是 axs.filter(fold(monoidPredicateAll)(isFoo,isBar,isBaz))
会有所帮助的地方。
我在 SO 上找到了关于这个的讨论,但它是关于 Java 和内置Predicate
类型的,所以没有直接解决我的问题。
是的,我想太多了:)