Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ramda.js 为什么compose应用从左到右的传感器?_Ramda.js_Javascript_Functional Programming_Transducer - Fatal编程技术网

Ramda.js 为什么compose应用从左到右的传感器?

Ramda.js 为什么compose应用从左到右的传感器?,ramda.js,javascript,functional-programming,transducer,Ramda.js,Javascript,Functional Programming,Transducer,示例代码: // Compose functionality const compose = (...fns) => { return args => { return fns.reduceRight((arg, fn) => fn(arg), args); } }; // List of transformation and predicate functions const add1 = x => x + 1; const isGreaterThan

示例代码:

// Compose functionality
const compose = (...fns) => {
  return args => {
    return fns.reduceRight((arg, fn) => fn(arg), args);
  }
};

// List of transformation and predicate functions
const add1 = x => x + 1;
const isGreaterThanThree = x => x > 3;
const times2 = x => x * 2;

// Concat and Sum reducers (or the thing that I want to build). 
/*
  In this case, I'm using concatReducer, but I can easily substitute concatReducer with
  sumReducer and change the initial value of the reduce method to zero.
*/
const concatReducer = (acc, el) => acc.concat(el);
const sumReducer = (acc, el) => acc += el;

// Transformation reducer (not sure the appropriate terminology)
const mapReducer = transform => {
  return reducer => {
    return (acc, el) => {
      return reducer(acc, transform(el));
    }
  }
};

// Predicate reducer (again, not sure the appropriate terminology here)
const filterReducer = predicate => {
  return reducer => {
    return (acc, el) => {
      return predicate(el) ? reducer(acc, el) : acc;
    }
  }
}

[1, 2, 3] 
  .reduce(
    compose(
      mapReducer(times2),
      filterReducer(isGreaterThanThree),
      mapReducer(add1),
    )(concatReducer),
    []
  );
我希望值是[8],而不是[5,7]

Compose是右关联(reduceRight),但在本例中,它的行为与左关联相同

我心里想,也许我的compose函数实现是错误的。 结果,我使用了R.compose,但得到了相同的结果


我做错什么了吗?或者,在处理传感器时,这是一种组合为左关联的场景吗?

引号和一些示例取自

什么是传感器? 传感器只是一个数的函数。唯一的参数是另一个传感器变压器(在代码库中标记为xf)

由于传感器只是一个参数的函数,因此可以通过函数组合轻松组合传感器,以创建变压器管道。请注意,传感器在调用时返回变压器

示例:(改编)

var映射器=函数(f){

返回函数(xf){/因为将组合传感器(
f,g,h
)应用于减速器(
r
),最左边的(
f
)变为最上面的,首先作用于最终参数
(acc,el)
到增广减速器
f(g(h(r))
:(*)


(*)因此您定义了函数,以便

mapReducer(foo)(reducer)(acc, el) 
  =~= reducer(acc, foo(el));

filterReducer(predicate)(reducer)(acc, el)
  =~= predicate(el) ? reducer(acc, el) : acc;

concatReducer(acc, el)
  =~= acc.concat(el);
最重要的是

compose(f,g,h,...,p,q)(r)
    =~= [f,g,h,...,p,q].reduceRight((acc, fn) => fn(acc), r);
    =~= f(g(h(...(p(q( r ))...)))
那么

[1, 2, 3] 
  .reduce(
    compose(
      f,               // f = mapReducer(times2),
      g,               // g = filterReducer(isGreaterThanThree),
      h                // h = mapReducer(add1),
      )(r),            // r = concatReducer
    []
  )
  =~= [1, 2, 3] .reduce( f(g(h(r))), [])     // rc = f(g(h(r)))
  =~= rc( rc( rc( [], 1),  2),  3)
  =~= rc( rc( f(g(h(r)))( [], 1),  2),  3)
  =~= rc( rc( mapReducer(times2)(g(h(r)))( [], 1 ),  2),  3)

           // mapReducer(foo   )(reducer)(acc, el)
           //                =~= reducer( acc, foo(el))

  =~= rc( rc( g(h(r))([], times2( 1)),  2),  3)
  =~= rc( rc( filterReducer(isGreaterThanThree)(h(r))([] , times2( 1)),  
            2), 
        3)

           // filterReducer(pred           )(reducer)(acc, el)
           //                =~= pred(el) ?  reducer( acc, el) : acc

  =~= rc( rc( isGreaterThanThree( twice1) ? h(r)(  [], twice1) : [],  
            2),          /* where twice1 = times2(1) 
                                  h = mapReducer( add1) */
        3)
  =~= rc( rc( isGreaterThanThree( twice1) ? r([], add1(twice1)) : [],  
            2),          /* where twice1 = times2(1) 
                                  r = concatReducer  */
        3)
  =~= rc( rc( isGreaterThanThree( twice1) ? [].concat(add1(twice1)) : [],  
            2),          /* where twice1 = times2(1) */
        3)
  =~= ...
我们可以看到,
mapReducer(times2)
首先开始处理列表的元素,然后按
进行过滤,其效果大于三个
,然后是
add1
的映射

在处理
[1,2,3]
时,首先完成
时间2
的映射(隐式地好像使其成为
[2,4,6]
),然后过滤(只剩下
[4,6]
),然后映射
add1
,最终结果实际上是
[5,7]

虽然没有创建中间结构,但却构建了一个复合减速器,由一个
reduce
使用,一步一步地沿着输入前进

因此,传感器是一种融合/分解技术。直观地说,嵌套褶皱应该融合,不需要通过内部褶皱创建临时结构,只有这样才能被包裹褶皱消耗;遵循传感器规程,我们才能实现这一点


因此,
mapReducer
filterReducer
的名称很糟糕。它们实际上是
mappingTransducer\u-Maker
(或just
mappingTransducer\u-Maker
)和
filteringTransducer\u-Maker
(或just
filteringTransducer
),其中

  • mapping(foo)
    是一种将
    foo
    应用于输入元件
    elt
    ,从而产生
    foo(elt)
    ,以及
  • filtering(pred)
    是一种过滤传感器,它根据谓词调用
    pred(el)
    过滤掉输入元素
    el
    ,或将其保留在其中
或者更确切地说,传感器增加其变元
减速机
,这样,当累加器和当前元素最终调用组合的、增加的减速机时,它在将结果传递到基本
减速机
之前,以规定的方式操纵元素和累加器:

mapping(foo)( filtering(pred)(reducer) )( acc, elt)
----------------------------------------(         )
 =~=
filtering(pred)(reducer)( acc, foo(elt) )
 =~=
pred( foo(elt) ) ? reducer( acc, foo(elt) ) : acc

因此,
映射(foo)
过滤(pred)
是根据他们的参数从右到左合成的,
reducer
;但是合成的reducer从顶部开始工作,从左到右跟踪传感器的效果——首先进行映射,然后进行过滤。

我问了一次,得到了。也许这有助于为迟来的答复道歉。如果我错了,请更正,但在我的例子中,concatReducer的组合仍然是从右到左,首先应用mapReducer(times2)、filterReducer(IsGreaterThree),然后应用mapReducer(add1),后者返回一个接受参数(x)的包装函数。然而,当x传递到包装函数时,x实际上进入mapReducer(times2)首先是其他功能。是否正确?@FNMT8L9IN82映射减速机和过滤器减速机实际上是传感器,而不是减速机。您合成传感器,合成的传感器应用于concatReducer,从而产生一个增强的减速机,用于实际元素和累加器版本(随着输入的进行而变化)。
[1,2,3]。reduce(f(g(h(r)),[])=[2,3]。reduce(f(g(h(r)),f(g(h(r))([],1))
根据
reduce
的定义。reducer接受对,
(acum,elemt)
。因此
x
在我的
compose
中是一对
(acum,elemt)
。这是象征性的。如果需要,请毫不犹豫地询问更多信息。:)感谢您的回复…我需要阅读多次才能理解这一点。
compose(f,g,h,...,p,q)(r)
    =~= [f,g,h,...,p,q].reduceRight((acc, fn) => fn(acc), r);
    =~= f(g(h(...(p(q( r ))...)))
[1, 2, 3] 
  .reduce(
    compose(
      f,               // f = mapReducer(times2),
      g,               // g = filterReducer(isGreaterThanThree),
      h                // h = mapReducer(add1),
      )(r),            // r = concatReducer
    []
  )
  =~= [1, 2, 3] .reduce( f(g(h(r))), [])     // rc = f(g(h(r)))
  =~= rc( rc( rc( [], 1),  2),  3)
  =~= rc( rc( f(g(h(r)))( [], 1),  2),  3)
  =~= rc( rc( mapReducer(times2)(g(h(r)))( [], 1 ),  2),  3)

           // mapReducer(foo   )(reducer)(acc, el)
           //                =~= reducer( acc, foo(el))

  =~= rc( rc( g(h(r))([], times2( 1)),  2),  3)
  =~= rc( rc( filterReducer(isGreaterThanThree)(h(r))([] , times2( 1)),  
            2), 
        3)

           // filterReducer(pred           )(reducer)(acc, el)
           //                =~= pred(el) ?  reducer( acc, el) : acc

  =~= rc( rc( isGreaterThanThree( twice1) ? h(r)(  [], twice1) : [],  
            2),          /* where twice1 = times2(1) 
                                  h = mapReducer( add1) */
        3)
  =~= rc( rc( isGreaterThanThree( twice1) ? r([], add1(twice1)) : [],  
            2),          /* where twice1 = times2(1) 
                                  r = concatReducer  */
        3)
  =~= rc( rc( isGreaterThanThree( twice1) ? [].concat(add1(twice1)) : [],  
            2),          /* where twice1 = times2(1) */
        3)
  =~= ...
mapping(foo)( filtering(pred)(reducer) )( acc, elt)
----------------------------------------(         )
 =~=
filtering(pred)(reducer)( acc, foo(elt) )
 =~=
pred( foo(elt) ) ? reducer( acc, foo(elt) ) : acc