转换函数(地图等)的 Ramda 无点问题

Ramda point-free problems with transform functions (map, etc)

我有这个功能,基本上是将请求参数和查询参数映射到一个SQL语句:

function selectSingleResult(params, { order, limit, offset, fields, runset_id, txOffset, txFactor }) {
      const transformer = R.when(R.equals('values'), R.compose(knex.raw.bind(knex), applyConversion({ txOffset, txFactor })))
      const newFields = R.map(transformer , fields);

      knex('myTable').select(...newFields) // etc...

理想情况下,我希望能够在函数外定义 transformer ,这样函数就可以变成:

const mapFields = R.map(transformer);
function selectSingleResult(params, { order, limit, offset, fields, runset_id, txOffset, txFactor }) {
      knex('myTable').select(...mapFields(fields)) // etc...

问题是 applyConversion 函数需要给 selectSingleResult 参数。

这是我将函数转换为 map 时遇到的一个常见问题。它们通常需要参数而不是被映射的值。在这种情况下,我怎样才能以无点或至少更可测试的风格编写,而不至于最终嵌套函数太多?

感觉好像您正在尝试在没有多大意义的代码中无意义。但是有一个相反的概念,即从第二个参数中解构一大组字段,这似乎不是必需的,所以这看起来很混乱。 (这实际上可能是必要的:也许您在主函数的其余部分中使用了 orderlimitoffsetrunset_id。)

我认为您只需再引入一层调用就可以几乎完成您所要求的,就像这样:

const transformer = (query) => 
  R .when (R .equals ('values'), field => knex .raw (applyConversion (query) (field)))

const mapFields = R.pipe (transformer, map)

const selectSingleResult = (params, query) => {
  knex ('myTable') .select (... mapFields (query) (query .fields)) 
  // etc...
}

我把第二个参数命名为你的main函数query;这是一个猜测,如果这令人困惑,请将 query 的所有实例替换为 foo 或对您有意义的内容。

注意mapFields也可以写成const mapFields = (query) => R.map (transformer (query)),但上面的版本似乎更简单。另请注意,我简化了 transformer 一点。当你无法完全到达那里时,我根本看不出有任何理由去尝试无积分。并且尝试将无点代码与 knex .raw 之类的 OO 结构混合在一起似乎会使事情变得混乱。

如果我没看错代码,我们也可以这样重写transformer

const transformer = (query) => (field) =>
  field == 'values' ? knex .raw (applyConversion (query) ('values')) : field

但我无法确定这是否是一种改进。