函数式 Ramda 在范围外传递函数参数

Functional Ramda Passing function parameter outside of scope

以下面的例子命令式JavaScript为例:

getAnimalList = (hasCat) => {
  const baseAnimals = { dog: animLib.dog(), bear: animLib.bear()};
  if(hasCat){
    baseAnimals.cat = animLib.cat();
  }
  return baseAnimals
}

我正在尝试使用 Ramda 以函数式风格编写此代码,但我能做到的唯一方法是让函数超出范围:

getAnimalList = (hasCat) => {
  const baseAnimals = { dog: animLib.dog(), bear: animLib.bear()};
  return when(always(hasCat), merge({hasCat: animLib.cat()}))(baseAnimals)
}

撇开 animLib 如何超出范围,我要解决的方法是 hasCat 从外部传递(如果这是一个问题) 如下:

getAnimalList = (hasCat) => {
  const baseAnimals = { dog: animLib.dog(), bear: animLib.bear()};
  const mergeCat = when(compose(equals(true), prop('hasCat')), 
              compose(merge({hasCat: animLib.cat()}), prop('baseAnimals')));
 return mergeCat({hasCat: hasCat, baseAnimals: baseAnimals});
}

但这使得代码非常冗长。有一个更好的方法吗?或者冗长只是保持代码更纯净的代价。

在我看来,这样做会很好:

getAnimalList = (animLib, hasCat) => {
  const baseAnimals = { dog: animLib.dog(), bear: animLib.bear()};
  return hasCat ? merge({hasCat: animLib.cat()}, baseAnimals) : baseAnimals;
}

因为 Ramda 的 whenifElse 是基于谓词函数而不是布尔值,所以在这里使用它们似乎有点过分了。

显然,如果你想要一个在范围内有 animLib 的版本,你可以柯里化这个函数,或者像 Ramda 的 curry 或者只是改变成

getAnimalList = (animLib) => (hasCat) => { /* ... */ }

然后就可以创建newAnimalList = getAnimalList(myAnimLib).