[英]Ramda Converting to Free-Point Style
I haven't really found a good resource for this sort of thing.我还没有真正找到这种事情的好资源。 Apologies in advance if this question has been asked, though I couldn't quite find the answer (perhaps due to a lack of knowing how to search.
如果有人问过这个问题,请提前道歉,尽管我找不到答案(可能是因为不知道如何搜索。
I have this function.我有这个 function。 It's like
R.prepend
/ R.append
, but it shoves a value into the middle of a list instead.就像
R.prepend
/ R.append
,但它将一个值推到列表的中间。
const insertMiddle = (val, arr) =>
R.insert(Math.floor(arr.length/2), val, arr);
I'm just learning functional programming, so I'm writing a program with as much free-point-style as possible.我只是在学习函数式编程,所以我正在编写一个尽可能多的自由点风格的程序。 Even if that takes away from readability a bit, I just like to see it done.
即使这会影响可读性,我只是希望看到它完成。 Bend my brain to start thinking functionally and seeing how to solve problems that way.
弯曲我的大脑,开始功能性地思考,看看如何以这种方式解决问题。
Here's what I've done:这是我所做的:
const halfLength = R.compose(
Math.floor,
R.divide(R.__, 2),
R.prop('length')
);
// ----
const insertMiddle = (val, arr) =>
R.insert(halfLength(arr), val, arr);
// ---- OR
const insertMiddle = (val, arr) =>
R.insert(halfLength(arr), val, R.identity(arr));
This of course isn't free-point yet.这当然还不是自由点。
Here is ostensibly the next step:这显然是下一步:
const insertMiddle = (val, arr) =>
R.insert(R.__, val)(halfLength(arr), R.identity(arr));
Now if I can get (halfLength(arr), R.identity(arr))
to be point-free, I'll be left with a function that just needs val
.现在,如果我可以得到
(halfLength(arr), R.identity(arr))
是无点的,我将得到一个只需要val
的 function 。
Am I going about this the right way?我会以正确的方式解决这个问题吗? What happens next?
接下来发生什么?
How does:如何:
x => foo(bar(x), x)
or x => foo(bar(x), x)
或x => foo(bar(x),baz(x))
become point free?成为免费点?
The R.chain called with two functions - chain(f, g)(x) is the equivalent of f(g(x), x).使用两个函数调用的 R.chain -chain(f, g)(x) 等效于 f(g(x), x)。 If with change the order of the last two parameters of R.insert (value & array), we can use it to create
insertMiddle
:如果改变 R.insert (value & array) 的最后两个参数的顺序,我们可以使用它来创建
insertMiddle
:
const { compose, divide, __, prop, curry, chain, insert } = R const halfLength = compose( Math.floor, divide(__, 2), prop('length') ) const flippedInsert = curry((idx, val, arr) => insert(idx, arr, val)) const insertMiddle = chain(flippedInsert, halfLength) const arr = [1, 2, 3, 4] const result = insertMiddle(arr)('*') console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>
Ramda does offer tools to make it easier to write points-free code. Ramda 确实提供了一些工具,可以更轻松地编写无点代码。 And if you are just fiddling around, trying to see how they work, we can do all sorts of things with them.
如果你只是在摆弄,想看看它们是如何工作的,我们可以用它们做各种各样的事情。 But I would reiterate that the goal should be understandable code.
但我要重申,目标应该是可理解的代码。 Use points-free when it helps with readability;
在有助于提高可读性时使用免积分; skip it when it doesn't.
没有的时候跳过它。
There are a few Ramda functions specifically designed for this.有一些专门为此设计的 Ramda 函数。 (Disclaimer: I'm a Ramda author.)
useWith
, converge
, and nthArg
are prominent among these. (免责声明:我是 Ramda 的作者。)
useWith
、 nthArg
converge
突出的。
We can use converge
and nthArg
to get this to work:我们可以使用
converge
和nthArg
来让它工作:
const {compose, divide, __, prop, converge, insert, pipe, nthArg} = R const halfLength = compose ( Math.floor, divide (__, 2), prop ('length') ) const insertMiddle = converge (insert, [pipe (nthArg (1), halfLength), nthArg (0), nthArg (1)]) console.log (insertMiddle (42, [1, 2, 3, 4, 5, 6]))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"></script>
We could even go whole-hog and inline halfLength
我们甚至可以 go Whole-hog 和 inline
halfLength
const insertMiddle = converge (insert, [
pipe (nthArg (1), prop ('length'), divide (__, 2), Math .floor),
nthArg (0),
nthArg (1)
])
Again, as a learning exercise, this is fine.同样,作为一个学习练习,这很好。 But I find either of those a lot less readable than a simple function, using only a bit of Ramda:
但我发现其中任何一个都比简单的 function 可读性差很多,只使用一点 Ramda:
const insertMiddle = (x, xs) =>
insert ((xs .length >> 1), x, xs)
or a plain vanilla version:或普通的香草版本:
const insertMiddle = (x, xs, mid = xs .length >> 1) =>
[... xs .slice (0, mid), x, ... xs .slice (mid)]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.