【问题标题】:Using R.pipe (or R.curry) to simplify functional method calls使用 R.pipe(或 R.curry)简化函数式方法调用
【发布时间】:2018-03-15 08:31:30
【问题描述】:

今天刚开始使用 Ramda,试图通过更具声明性来学习/将函数式编程整合到我的代码中,但我无法弄清楚如何使用管道(或 curry?)使其更加精简只用过一次,也许我在努力。

任何人都可以解释如何减少它以使其看起来不那么混乱,以便我可以了解 FP 吗?如果我分离出每个方法并像工作示例中那样单独调用,我似乎只能做到这一点。为简洁起见,对示例进行了简化。

工作示例

const logLevels: string[] = ['log', 'info', 'debug', 'error'];

// maps logLevels into pairs: [[log: f(x)], ['info': f(x)], ...]
const toPairs = (logLevel: string) => [logLevel, debug(`${process.env.APP_NAME}:${namespace}:${logLevel}`)];
const loggers: any = R.map(toPairs, logLevels);

// Then takes the pairs and makes it an object
// Output: { log: f(x), info: f(x), debug: f(x), ...}
this.debugger = R.fromPairs(loggers);

// Example Usage:
// this.debugger.log('...');

【问题讨论】:

  • 看起来你可能已经自己解决了,但以后考虑给出预期的输出和用法。第一次阅读我不清楚你想在this.debugger上创建一堆方法
  • 为什么我在这个问题上得了-1?这个问题有一个我正在研究的例子,只问如何将它从 4 条单独的线带到使用管道的东西。我已经说过问题中的示例有效,但由于我是 FP 的新手,所以我不明白如何提高效率
  • @RossMackay 我不确定你是如何误解这个问题的。我只问如何使用我的working example(因为它已经工作了,但分为 4 个部分)并使用管道或其他 FP 方法使其不那么混乱。我认为toPairs 上面的数组对示例和最后使用this.debugger 就足够了,但为了清楚起见,即使示例用法是this.debugger.log(...),我已经添加了被放入@的输出987654327@
  • 要清楚 -1 不是我,但我正在寻找的是您添加的示例输出。误解来自函数与this.debugger的绑定,这与函数应该输出什么无关。

标签: node.js functional-programming ramda.js


【解决方案1】:

我会使用reduce

const logLevels = ['log', 'info', 'debug', 'error'];
const debugger = reduce(
  (dbg, level) => assoc(
    level, 
    debug(`${process.env.APP_NAME}:${namespace}:${level}`),
    dbg
  ), {}, logLevels)

debugger.info('hello, world')

您可以在 Ramda REPL 上看到这一点,我不得不将名称从 debugger 更改为浏览器中的保留名称。

【讨论】:

  • 感谢 REPL 链接,我用这个来了解它是如何工作的。你会不会把它分开,让它自我记录更多,或者这对于你通常在 FP 中所期望的非常典型?
  • 另外,APP_NAMEnamespace 没有被传递以使函数不纯,这有关系吗?目标是始终拥有纯函数,还是因为它没有被重用就可以了?
  • 我可能会抽出一个函数将其写为reduce(addDebuggerMethod, {}, log levels) ,但我可能不会打扰,因为它对我来说仍然可读,而且我不太可能拒绝该函数。
  • 你必须自己划清哪些地方可以允许杂质。几乎可以肯定你的程序会有一些(IO 有人吗?)我喜欢尝试将它们保持在系统的边缘并保持核心纯净。但是debug 对象几乎肯定不会是纯粹的,所以我不太可能在这里关注它。
【解决方案2】:

在我注意到 Ramda API 使传递到管道的参数成为链式方法中的第二个参数后,管道开始工作,即。 R.map 而不是像 Elixir 这样的第一个参数,我这个周末正在玩它作为介绍:

const logLevels = ['log', 'info', 'debug', 'error'];
const toPairs = (logLevel: string): any => [logLevel,
this.debugger = R.pipe(R.map(toPairs), R.fromPairs)(logLevels);

如果有人有任何其他建议,我会全力以赴:)

【讨论】:

    猜你喜欢
    • 2016-03-28
    • 2011-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多