javascript - 在管道中重用变量的功能方法

标签 javascript functional-programming ramda.js

将 javascript 和 typescript 中的函数式编程与 Ramda 结合使用,我经常发现自己编写的代码如下:

const myFun = c => {
  const myId = c.id

  const value = pipe(
    getAnotherOtherPropOfC,
    transformToArray,
    mapToSomething,
    filterSomething,
    // ... N other transformations
    // ok now I need myId and also the result of the previous function
    chainMyIdWithResultOfPreviousFunction(myId)
  )(c)

  return value
}

注意创建 const myId 如何打破无点样式。我想写 myFun 这样就不需要显式 c 了。所以像: const myFun = pipe(....)

我想知道是否有一种更实用、更易读的方式来做这样的事情。

最佳答案

可以做到吗?当然。 应该这样做吗?不是很清楚。

这是上面的无点版本,使用lift:

const getAnotherOtherPropOfC = prop ('x')
const transformToArray = split (/,\s*/)
const mapToSomething = map (Number)
const filterSomething = filter (n => n % 2 == 1)
const square = (n) => n * n
const chainMyIdWithResultOfPreviousFunction = (id) => (arr) => `${id}: [${arr}]`

const myFun = lift (chainMyIdWithResultOfPreviousFunction) (
  prop ('id'),
  pipe(
    getAnotherOtherPropOfC,
    transformToArray,
    mapToSomething,
    filterSomething,
    map (square)
  )
)

console .log (
  myFun ({id: 'foo', x: '1, 2, 3, 4, 5'}) // => 'foo: [1,9,25]'
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script> const {prop, split, map, filter, lift, pipe} = R            </script>

lift是比 Ramda 的 converge 更符合 FP 标准的函数(与 useWith 一起提供了制作无点解决方案的方法,通常以牺牲可读性为代价。)lift 在应用于函数时与 converge 重叠,但被设计为对于一元函数,其中 converge 处理多元函数。

这并不可怕。但与原版相比,它的唯一优势是它没有积分。如果您尝试将其扩展到该管道中的中间函数,它将变得非常丑陋。

我的看法是,无点有时可以带来更清晰、更易于阅读和更易于维护的代码。但是,如果不这样做,就没有理由不计分。

这并不是说 point-free 本质上比 pointed 代码更实用。我认为这个想法最初是对其他语言的一种 Haskell 嫉妒。 Haskell 被认为是一种理想化的 FP 语言,它恰好是一种自然而然地出现无点的语言。但这至少部分是巧合。

我的标准示例是 const sum = reduce(add, 0)const sum = (xs) => xs.reduce(add, 0)。它还非常清楚地表明了与 const product = reduce(multiply, 1)const all = reduce(and, true) 的相似之处。但随着您变得越来越复杂,或者当您需要重用中间计算时(正如 Bergi 指出的那样),无点代码通常会成为一种负担。

关于此版本是否是对原始版本的改进,我在这里没有真正的意见。如果是这样,那只是一个小问题。进一步携带它会显着降低可读性。

关于javascript - 在管道中重用变量的功能方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58199319/

相关文章:

ios - 如何在 App 开发中使用函数式编程

javascript - 使用 R.set 或 R.merge 时,ramda.js 是否会创建原始对象的深度克隆?

java - 如何使用 XML 从站点生成 HTML

javascript - 通过云码删除解析文件

javascript - 如何验证 Angular 国家/地区的手机号码?

.net - F# 函数返回值

javascript - 动态重新加载该表单后无法发送表单

Java 8 添加元素的方式

javascript - 具有属性功能的多级 groupby

javascript - 删除 if 语句