javascript - Functional way of re-using variables in a pipe
问题描述
Using functional programming in javascript and typescript together with Ramda, I often find myself writing code like:
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
}
Notice how creating a const myId
breaks point-free style. I'd like to write myFun
so that there's no need to explicit c
. So something like:
const myFun = pipe(....)
I was wondering if there's a more functional and readable way of doing things like this.
解决方案
可以做到吗?当然。 应该这样做吗?这不是很清楚。
这是上述的无点版本,使用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 更符合 FP 标准的函数converge
(它与useWith
提供无点解决方案的方法一起,通常以牺牲可读性为代价。) 与应用于函数时lift
重叠,但设计用于处理多元函数的一元函数。converge
converge
这并不可怕。但它与原版相比的唯一优势是它是无点的。如果你试图将它扩展到该管道中的中间函数,它会变得非常难看。
我的看法是,无点有时会导致代码更清晰、更易于阅读和更易于维护。但是,如果不这样做,就没有理由去无点。
这并不是说无指向代码本质上比指向代码更实用。我认为这个想法始于对其他语言的一种 Haskell 嫉妒。Haskell 被认为是一种理想化的 FP 语言,而它恰好是一种自然而然地出现无点的语言。但这至少部分是巧合。
我的标准示例是const sum = reduce(add, 0)
比const sum = (xs) => xs.reduce(add, 0)
. 它也非常清楚地与const product = reduce(multiply, 1)
or的相似之处const all = reduce(and, true)
。但是当您变得更加复杂,或者当您需要重用中间计算时(正如 Bergi 指出的那样),无点代码通常会成为一种负担。
关于这个版本是否是对原版的改进,我在这里没有真正的电话。如果是这样,那只是小事。进一步携带它会显着降低可读性。
推荐阅读
- javascript - ReactJS:将用户对象作为道具传递给组件会导致其值未定义
- c++ - 大整数 & C
- ruby-on-rails - 计算图像在屏幕上出现的次数错误
- c++ - 使用 clang 预处理器将 C++ 源文件连接成一个
- java - Java Int[] 数组返回字节。为什么?
- firebase - StorageReference updateMetadata 覆盖所有属性
- c++ - 在 WriteConsoleOutputCharacter C++ 中使用换行符
- python - 具有全年日期时间索引的 matplotlib 散点图
- python - 如何阻止 Pandas (Python) 读取我希望它跳过的行中的分隔符?
- c# - PowerShell 和 LuaInterface.dll