使用Ramda,你如何构成二进制函数?

Eva*_*oll 3 javascript functional-programming ramda.js

Ramda提供了一个区分大小写的equals R.equals,但是我想要一个不区分大小写的相等测试.拉姆达也提供R.compose,但在拉姆达组合中,假设最左边的论点是一元的.

我想做的就像是

R.compose( R.equals(...), R.toLower )
Run Code Online (Sandbox Code Playgroud)

但是,我想组成R.toLower二进制函数R.equals

有没有办法实现这个目标?类型喜欢

(b->b->c) -> (a->b) => (a->a->c)
Run Code Online (Sandbox Code Playgroud)

我想要的是Haskell的Data.Function.on定义为

on b u x y运行在施加一元函数的结果的二值函数b u到两个参数xy.从相反的角度来看,它可以转换两个输入并组合输出.

JLR*_*she 5

编辑: R.useWith非常接近您正在寻找的:

接受函数fn和变换器函数列表,并返回一个新的curried函数.当调用新函数时,它调用函数fn,其参数包括在新函数的连续参数上调用每个提供的处理程序的结果.

所以你可以像这样定义你的函数:

const equalsi = R.useWith(R.equals, [R.toLower, R.toLower]);
Run Code Online (Sandbox Code Playgroud)

例:

const equalsi = R.useWith(R.equals, [R.toLower, R.toLower]);

const check = (a, b) => console.log(`${a} = ${b}?`, equalsi(a, b));

check('aaa', 'aaa');
check('aaa', 'aa');
check('aAa', 'aaa');
check('aaa', 'aAa');
check('aba', 'aaa');
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.0/ramda.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

如果你想要一些与on你提到的Haskell 函数等效的东西,你可以按如下方式定义:

const on = (b, u) => R.useWith(b, [u, u]);
const equalsi = on(R.equals, R.toLower);

const check = (a, b) => console.log(`${a} = ${b}?`, equalsi(a, b));

check('aaa', 'aaa');
check('aaa', 'aa');
check('aAa', 'aaa');
check('aaa', 'aAa');
check('aba', 'aaa');
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.0/ramda.min.js"></script>
Run Code Online (Sandbox Code Playgroud)


上一个答案:

可能有更优雅的方式来做到这一点,但这有效:

const equalsi = R.unapply(R.compose(
    R.apply(R.equals),
    R.map(R.toLower)
));
Run Code Online (Sandbox Code Playgroud)

打破它:

// [] -> Boolean
// Takes an array of two strings and returns true if they are equal
R.apply(R.equals)

// [] -> Boolean
// Takes an array of two strings, converts them to lowercase, and returns true
// if those lowercase strings are equal
R.compose(R.apply(R.equals), R.map(R.toLower))

// String -> String -> Boolean
// Takes two strings, converts them to lowercase, and returns true if those lowercase
// string are equal
R.unapply(R.compose(R.apply(R.equals), R.map(R.toLower)));
Run Code Online (Sandbox Code Playgroud)

您还可以on根据Ramda函数定义函数,然后使用:

const on = (b, u) => R.unapply(R.compose(R.apply(b), R.map(u));

const equalsi = on(R.equals, R.toLower);
Run Code Online (Sandbox Code Playgroud)