你会如何使用 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 :)