简体   繁体   English

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

[英]Using Ramda, how do you compose against binary functions?

Ramda provides a case-sensitive equals with R.equals , however I want a case-insensitive equality test. Ramda提供与R.equals大小写相等的区分,但是我想要一个不区分大小写的相等测试。 Ramda also provides R.compose , but in the Ramda composition, it's assumed the left most argument is unary. R.compose还提供了R.compose ,但在R.compose组合中,假设最左边的参数是一元的。

What I want to do is something like 我想做的就像是

R.compose( R.equals(...), R.toLower )

But, I want to compose the R.toLower on the binary function R.equals ? 但是,我想组成R.toLower上的二元函数R.equals

Is there a method to accomplish this? 有没有办法实现这个目标? Types likes 类型喜欢

(b->b->c) -> (a->b) => (a->a->c)

What I want is something like Haskell's Data.Function.on which is defined as 我想要的是像Haskell的Data.Function.on这样定义为

on buxy runs the binary function b on the results of applying unary function u to two arguments x and y . on buxy运行二进制函数b,将一元函数u应用于两个参数xy From the opposite perspective, it transforms two inputs and combines the outputs. 从相反的角度来看,它可以转换两个输入并组合输出。

EDIT: R.useWith comes very close to what you're looking for: 编辑: R.useWith非常接近您正在寻找的:

Accepts a function fn and a list of transformer functions and returns a new curried function. 接受函数fn和变换器函数列表,并返回一个新的curried函数。 When the new function is invoked, it calls the function fn with parameters consisting of the result of calling each supplied handler on successive arguments to the new function. 当调用新函数时,它调用函数fn,其参数包括在新函数的连续参数上调用每个提供的处理程序的结果。

So you can define your function like this: 所以你可以像这样定义你的函数:

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

Example: 例:

 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'); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.0/ramda.min.js"></script> 

If you wanted something equivalent to the Haskell on function that you mention, you could define one as follows: 如果你想要的东西等同于哈斯克尔on功能,你别说,你可以定义一个如下:

 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'); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.0/ramda.min.js"></script> 


Previous answer : 上一个答案

There may be a more elegant way to do this, but this works: 可能有更优雅的方式来做到这一点,但这有效:

const equalsi = R.unapply(R.compose(
    R.apply(R.equals),
    R.map(R.toLower)
));

Breaking it down: 打破它:

// [] -> 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)));

You could also define your on function in terms of Ramda functions and then use that: 您还可以根据Ramda函数定义on函数,然后使用:

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

const equalsi = on(R.equals, R.toLower);

There is also eqBy that you may want to consider: 您还可以考虑使用eqBy

Takes a function and two values in its domain and returns true if the values map to the same value in the codomain; 在其域中获取一个函数和两个值,如果值映射到codomain中的相同值,则返回true; false otherwise. 否则是假的。

R.eqBy(R.toLower, 'a', 'A'); //=> true

Example: 例:

 console.log(R.eqBy(R.toLower, 'a', 'A')) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.0/ramda.min.js"></script> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM