简体   繁体   English

Ramda-R.both与咖喱谓词

[英]Ramda - R.both with curried predicates

My goal is to link two predicates that take the same two parameters in a R.both such that I can pass the parameters independently - ie curried. 我的目标是在R.both中链接采用相同两个参数的两个谓词,以便我可以独立传递参数-即curried。

Here's the repl implementation I put together: 这是我整理的repl实现:

const isXEqual = (obj1, obj2) => R.equals(obj1.x, obj2.x);
const isYEqual = (obj1, obj2) => R.equals(obj1.y, obj2.y);

const a = R.curry(isXEqual);
const b = R.curry(isYEqual);

const isBoth_Curried = R.both(a, b);

const obj1 =  {"x": 6, "y": 5};
const obj2 =  {"x": 6, "y": 5};
const obj3 =  {"x": 5, "y": 5};

isBoth_Curried(obj1, obj2); //==> true
isBoth_Curried(obj1, obj3); //==> false

isBoth_Curried(obj1)(obj2); //==> true

But: isBoth_Curried(obj1)(obj3); //==> true 但是: isBoth_Curried(obj1)(obj3); //==> true isBoth_Curried(obj1)(obj3); //==> true

Really confused - what am I missing here? 真的很困惑-我在这里想念什么?

I think Ramda's both is slightly out of sync with the majority of the library (disclaimer: I'm one of the Ramda authors.) The result of both probably should be curried to the maximum length of its arguments, as happens with its close affiliate allPass . 我认为Ramda的both与大多数库both略有不同步(免责声明:我是Ramda的作者之一。)这both的结果都应尽量考虑到其参数的最大长度,就像它的紧密会员一样allPass So this should work the way you expect. 因此,这应该可以按您期望的方式工作。

But, I think you are missing something basic, as you suggest. 但是,正如您所建议的,我认为您缺少一些基本知识。 It doesn't matter that the inner functions are curried. 内部函数没有关系。 They will only be called once, with all arguments: 它们将仅被调用一次,并带有所有参数:

R.both(a, b)(obj1)(obj3)                 //~> [1]

(function () {
  return a.apply(this, arguments) && a.apply(this, arguments);
})(obj1)(obj3)                           //~> [2]

(isXEqual(obj1) && isYEqual(obj1))(obj3) //~> [3]

(isYEqual(obj))(obj3)                    //~> [4]

R.equals(obj1.y, obj2.y)                 //~> [5]

R.equals(5, 5)                           //=> [6]

true

The step that's most likely tripping you up is [3], (isXEqual(obj1) && isYEqual(obj1))(obj3) ~> (isYEqual(obj))(obj3) . 最可能使您绊倒的步骤是[3], (isXEqual(obj1) && isYEqual(obj1))(obj3) (isYEqual(obj))(obj3) (isXEqual(obj1) && isYEqual(obj1))(obj3) 〜> (isYEqual(obj))(obj3) The point is that isXEqual(obj1) is, because of your currying, a function, as is isYEqual(obj1) . 问题的关键是, isXEqual(obj1)是因为你的钻营,一个功能,因为是isYEqual(obj1) Both of these are truth-y, so && returns the second one. 这两个都是真-y,因此&&返回第二个。

That should explain what's going on. 那应该解释发生了什么。

I do think Ramda's both function should be updated. 我确实认为Ramda的both功能都应该更新。 But you can make this work, as others have suggested, by currying the result of both . 但是您可以像其他人所建议的那样,通过计算both的结果来使这项工作有效。


One more point: you can write isXEqual / isYEqual more simply with Ramda's eqProps : 还有一点:您可以使用isXEqual isYEqual更简单地编写isXEqual / eqProps

const isXEqual = R.eqProps('x')
const isYEqual = R.eqProps('y')

I think that R.both is not curried by default. 我认为R.both默认情况下不被管理。 If you do R.curryN(2, R.both(a, b)) then it works as one expects. 如果您执行R.curryN(2, R.both(a, b))那么它将按预期工作。 Look at this REPL to see an example. 查看此REPL以查看示例。

According the Ramda's source for both 根据Ramda的源both

var both = _curry2(function both(f, g) {
  return _isFunction(f) ?
    function _both() {
      return f.apply(this, arguments) && g.apply(this, arguments);
    } :
    lift(and)(f, g);
});

if the first parameter is a function, you are not returned a curried function. 如果第一个参数是一个函数,则不会返回已管理的函数。

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

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