在拉姆达召唤两次Arg

时间:2016-09-16 19:24:18

标签: javascript ramda.js

我正在使用Ramda构建一个简单的应用程序。

我遇到了一个功能性构图问题,我不确定如何解决这个问题而不会创造一个看似不必要的荒谬功能。

情景:

我有一个对象作为参数传递。这个对象有两个属性,还有一些与问题无关的东西,除了我不想改变它的状态:

{locCode :<string>, LocationList : [<Location>], someOtherParams : ...  } 

我有一个arg函数可以将locCode转换为一个位置: fetchLocByCode

我想要的结果是获取locCode值,将其传递给fetchLocByCode,将LocationList附加到结果中,然后返回一个包含新LocationList的新对象没有触及对象上的任何其他内容。

有点类似于:

(Param)=>{
Param.LocationList.push(fetchLocByCode(Param.locCode));
return Param;
}

我写完这篇文章似乎非常荒谬,让我相信自己做了一件可怕的错事:

const locListLens = R.lens(R.prop('LocationList'),R.assoc('LocationList'))
const appendLocList = (i)=>R.compose(R.over(locListLens),R.append,fetchLocByCode,R.prop('locCode'))(i)(i)

此解决方案的工作原理是&#39;但似乎我错过了一些基本的想法。

是否有人愿意提出更多的规范&#39;解决这种情况的方法是什么?

1 个答案:

答案 0 :(得分:3)

让我们从您的初始版本开始:

Param => {
  Param.LocationList.push(fetchLocByCode(Param.locCode));
  return Param;
}

我非常希望不需要突变。我们将其删除:

Param =>
  R.assoc('LocationList',
          R.append(fetchLocByCode(Param.locCode), Param.LocationList),
          Param)

我们可以使用镜头避免两次访问LocationList属性:

Param =>
  R.over(R.lensProp('LocationList'),
         R.append(fetchLocByCode(Param.locCode)),
         Param)

我们可以完全摆脱Param吗?我们首先使用R.converge

R.converge(R.over(R.lensProp('LocationList')),
           [Param => R.append(fetchLocByCode(Param.locCode)),
            R.identity])

让我们使用R.compose从第一个分支函数中删除Param

R.converge(R.over(R.lensProp('LocationList')),
           [R.compose(R.append, fetchLocByCode, R.prop('locCode')),
            R.identity])

每当你发现自己写R.converge(f, [g, R.identity])时,你就发现了S组合子的用途!

S.S(R.flip(R.over(R.lensProp('LocationList'))),
    R.compose(R.append, fetchLocByCode, R.prop('locCode')))

虽然这很整洁,但我认为R.assoc版本没问题。未来的读者不会喜欢理解S.S(R.flip(R.over(R.lensProp。 ;)