你会如何使用 R.o 编写 R.compose?
how would you write R.compose using R.o?
似乎有些人习惯于了解一个好的模式,从一个二元函数中创建一个 n 步组合或管道。也许这是显而易见的或常识。
我试图做的是 R.either(predicate1, predicate2, predicate3, ...)
但 R.either
是这些二元函数之一。我认为 R.composeWith
可能是一个好的解决方案的一部分,但没有让它正常工作。然后我认为 R.o
是它的核心,或者也许 R.chain
不知何故。
也许有一种完全不同的方法可以使 n 元 either
比 "compose-with"(R.either)
更好...如果有兴趣但想问一个比这更一般的问题。
将二元函数转换为带有多个参数的函数的一种常见方法是使用 R.reduce
。这至少要求二元函数的参数与其 return 类型为同一类型。
对于 R.either
的示例,它看起来像:
const eithers = R.reduce(R.either, R.F)
const fooOr42 = eithers([ R.equals("foo"), R.equals(42) ])
这接受一个谓词函数列表,每个函数将作为参数提供给 R.either
。
上面的fooOr42
例子相当于:
const fooOr42 = R.either(R.either(R.F, R.equals("foo")), R.equals(42))
如果要将函数从接受参数列表转换为可变数量的参数,也可以使用 R.unapply
。
const eithers = R.unapply(R.reduce(R.either, R.F))
const fooOr42 = eithers(R.equals("foo"), R.equals(42))
上述方法可用于任何可以组合以产生相同类型的值的类型,其中该类型具有一些“monoid”实例。这只是意味着我们有一个将两种类型组合在一起的二元函数和一些“空”值,它满足一些简单的法则:
- 关联性:
combine(a, combine(b, c)) == combine(combine(a, b), c)
- 左身份:
combine(empty, a) == a
- 正确身份:
combine(a, empty) == a
具有幺半群实例的一些常见类型示例包括:
- 数组,其中空列表是空值,
concat
是二进制函数。
- numbers,其中
1
是空值,multiply
是二进制函数
- numbers,其中
0
是空值,add
是二进制函数
在您的示例中,我们有谓词(一个函数 returning a boolean
值),其中空值是 R.F
(a.k.a (_) => false
),二元函数为R.either
。您还可以使用 R.both
和空值 R.T
(a.k.a (_) => true
) 组合谓词,这将确保生成的谓词满足所有组合谓词。
可能还值得一提的是,您也可以只使用 R.anyPass
:)
似乎有些人习惯于了解一个好的模式,从一个二元函数中创建一个 n 步组合或管道。也许这是显而易见的或常识。
我试图做的是 R.either(predicate1, predicate2, predicate3, ...)
但 R.either
是这些二元函数之一。我认为 R.composeWith
可能是一个好的解决方案的一部分,但没有让它正常工作。然后我认为 R.o
是它的核心,或者也许 R.chain
不知何故。
也许有一种完全不同的方法可以使 n 元 either
比 "compose-with"(R.either)
更好...如果有兴趣但想问一个比这更一般的问题。
将二元函数转换为带有多个参数的函数的一种常见方法是使用 R.reduce
。这至少要求二元函数的参数与其 return 类型为同一类型。
对于 R.either
的示例,它看起来像:
const eithers = R.reduce(R.either, R.F)
const fooOr42 = eithers([ R.equals("foo"), R.equals(42) ])
这接受一个谓词函数列表,每个函数将作为参数提供给 R.either
。
上面的fooOr42
例子相当于:
const fooOr42 = R.either(R.either(R.F, R.equals("foo")), R.equals(42))
如果要将函数从接受参数列表转换为可变数量的参数,也可以使用 R.unapply
。
const eithers = R.unapply(R.reduce(R.either, R.F))
const fooOr42 = eithers(R.equals("foo"), R.equals(42))
上述方法可用于任何可以组合以产生相同类型的值的类型,其中该类型具有一些“monoid”实例。这只是意味着我们有一个将两种类型组合在一起的二元函数和一些“空”值,它满足一些简单的法则:
- 关联性:
combine(a, combine(b, c)) == combine(combine(a, b), c)
- 左身份:
combine(empty, a) == a
- 正确身份:
combine(a, empty) == a
具有幺半群实例的一些常见类型示例包括:
- 数组,其中空列表是空值,
concat
是二进制函数。 - numbers,其中
1
是空值,multiply
是二进制函数 - numbers,其中
0
是空值,add
是二进制函数
在您的示例中,我们有谓词(一个函数 returning a boolean
值),其中空值是 R.F
(a.k.a (_) => false
),二元函数为R.either
。您还可以使用 R.both
和空值 R.T
(a.k.a (_) => true
) 组合谓词,这将确保生成的谓词满足所有组合谓词。
可能还值得一提的是,您也可以只使用 R.anyPass
:)