以无点风格在Ramda中编写一个无参数函数
Writing a parameterless function in Ramda in a point free style?
考虑下面的工作代码:
var randN = x => () => Math.floor(x*Math.random());
var rand10 = randN(10)
times(rand10, 10) // => [6, 3, 7, 0, 9, 1, 7, 2, 6, 0]
randN
是一个函数,它接受一个数字并返回一个RNG,当被调用时,该RNG将返回一个范围为[0,N-1]的随机int。所以这是一个特定RNG的工厂。
我一直在使用ramda.js,学习函数式编程理论,我的问题是:是否可以使用ramda以无点风格重写randN
?
例如,我可以写:
var badAttempt = pipe(multiply(Math.random()), Math.floor)
这将满足";无点风格";要求,但行为方式与randN
不同:调用badAttempt(10)
只返回1到10之间的单个随机数,而不是在调用时生成1到10间随机数的函数。
我一直找不到一个ramda函数的组合,使我能够以无点的风格进行重写。我不知道这是我的失败,还是使用random
的特殊之处,它破坏了引用的透明度,因此可能与无点样式不兼容。
更新
在与Denys讨论后,我自己对解决方案的细微变化:
randN = pipe(always, of, append(Math.random), useWith(pipe(multiply, Math.floor)), partial(__,[1,1]))
这将有助于使用一个额外的函数来抽象函数,以便在每次调用函数时重新评估其参数。
thunk = fn => R.curryN(fn.length, (...args) => () => fn(...args))
该函数的唯一目的是在给定的fn
函数中引起一些副作用。
一旦我们有了thunk
函数,我们就可以这样定义randN
:
randN = thunk(R.pipe(S.S(R.multiply, Math.random), Math.floor))
R.times(randN(10), 5) // e.g. [1, 6, 9, 4, 5]
注意:这里的S.S
是Sanctuary的S组合子,它的作用与R.converge(multiply, [Math.random, identity])
相同。
然而,我只建议使用无点解决方案,如果它确实提高了函数的可读性。
我不知道使用特定库学习函数编程是否是个好主意,因为库的特性和函数范式不可避免地会混合在一起。然而,在实践中,Ramda非常有用。它弥合了Javascript:D中命令性现实和功能性幻想之地之间的差距
这是一种手动方法:
// a few generic, reusable functions:
const comp = f => g => x => f(g(x)); // mathematical function composition
const comp2 = comp(comp)(comp); // composes binary functions
const flip = f => x => y => f(y)(x); // flips arguments
const mul = y => x => x * y; // first class operator function
// the actual point-free function:
const randN = comp2(Math.floor)(flip(comp(mul)(Math.random)));
let rand10 = randN(10); // RNG
for (let i = 0; i < 10; i++) console.log(rand10());
值得一提的是,randN
是不纯的,因为根据定义,随机数是不纯的。
var randN = R.converge(R.partial, [R.wrap(R.pipe(R.converge(R.multiply, [Math.random, R.identity]), Math.floor), R.identity), R.of])
var rand10 = randN(10)
alert(R.times(rand10, 10)) // => [3, 1, 7, 5, 7, 5, 8, 4, 7, 2]
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.19.1/ramda.js"></script>
- 函数参数中的数据与指定变量之间的任何性能差异
- AngularJS:我可以跳过函数参数回调吗
- 函数未将值作为参数传递
- JS:检查URL中的参数,然后迭代一个参数为var的函数
- 为什么不'我们在javascript中使用函数参数的数据类型
- 你好,这是测试用例,我必须在函数中传递n个参数
- JavaScript - 多参数函数,它是多个图像库的字符串
- 如何从两个参数函数返回随机整数
- 以无点风格在Ramda中编写一个无参数函数
- JS:将单参数函数转换为可链接函数
- 正则表达式类似于Javascript中的参数函数
- 将 $' 值传递给替换的关联参数函数
- "这个“;在参数函数中
- 如何向jquery插件发送参数函数
- 将参数函数Node.js从一个js传递到另一个js
- 如何在javascript参数函数中传递PHP post方法字符串
- 装饰 Javascript Promise.then 以便参数函数接收附加参数
- 正在分析setInterval ID'是的's参数函数
- 如何根据一个参数函数计算年龄
- 对象参数/函数和/或三元运算符混淆