首页 > 解决方案 > 您将如何使用 Ro 编写 R.compose?

问题描述

似乎知道一个好的模式可以从二进制函数中创建一个 n 步组合或管道。也许这是显而易见的或常识。

我试图做的R.either(predicate1, predicate2, predicate3, ...)只是R.either这些二进制函数之一。我认为R.composeWith可能是一个好的解决方案的一部分,但没有让它正常工作。然后我认为R.o是它的核心,或者也许是R.chain某种方式。

either也许有一种完全不同的方法可以制作一个比"compose-with"(R.either)... 感兴趣但试图问一个比这更普遍的问题更好的 n 元。

标签: ramda.js

解决方案


将二进制函数转换为带有多个参数的函数的一种常见方法是使用R.reduce. 这至少要求二进制函数的参数及其返回类型是相同的类型。

对于您的示例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

具有 monoid 实例的常见类型的一些示例包括:

  • 数组,其中空列表是空值并且concat是二进制函数。
  • 数字,其中1是空值,multiply是二进制函数
  • 数字,其中0是空值,add是二进制函数

在您的示例中,我们有谓词(返回boolean值的函数),其中空值是R.F(aka (_) => false),二进制函数是R.either. 您还可以使用R.both空值R.T(aka (_) => true) 组合谓词,这将确保生成的谓词满足所有组合谓词。

可能还值得一提的是,您也可以只使用R.anyPass:)


推荐阅读