Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/441.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 以无点风格在Ramda中编写无参数函数?_Javascript_Functional Programming_Ramda.js - Fatal编程技术网

Javascript 以无点风格在Ramda中编写无参数函数?

Javascript 以无点风格在Ramda中编写无参数函数?,javascript,functional-programming,ramda.js,Javascript,Functional Programming,Ramda.js,考虑以下工作代码: 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]范围内的随机整数。因此,它是一个特定RNG的工厂 我一直在使用并学习函数式编程理论,我的问题是:是否可以使用r

考虑以下工作代码:

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]范围内的随机整数。因此,它是一个特定RNG的工厂

我一直在使用并学习函数式编程理论,我的问题是:是否可以使用ramda以无点方式重写
randN

例如,我可以写:

var badAttempt = pipe(multiply(Math.random()), Math.floor)
这将满足“无点样式”要求,但与
randN
的行为方式不同:调用
badtreant(10)
只返回1到10之间的单个随机数,而不是调用时生成1到10之间随机数的函数

我还没有找到一个ramda函数的组合,使我能够以无点方式进行重写。我不知道这是否只是我的一个失败,或者使用
random
,这会破坏引用透明度,因此可能与无点样式不兼容

更新 在与Denys讨论后,我自己对解决方案的细微变化:

randN = pipe(always, of, append(Math.random), useWith(pipe(multiply, Math.floor)), partial(__,[1,1]))
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)
警报(R.times(rand10,10))/=>[3,1,7,5,7,5,8,4,7,2]

这将有助于使用额外的函数来抽象函数,以便在每次调用函数时重新计算其参数

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
这是一个与
R.converge(乘法,[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());
//一些通用的、可重用的函数:
常数comp=f=>g=>x=>f(g(x));//数学函数合成
常数comp2=comp(comp)(comp);//组成二进制函数
常数翻转=f=>x=>y=>f(y)(x);//反驳论点
常数mul=y=>x=>x*y;//一类算子函数
//实际的无点功能:
const randN=comp2(数学楼层)(翻转(comp(mul)(数学随机));
设rand10=randN(10);//RNG
对于(让i=0;i<10;i++)console.log(rand10());

值得一提的是,
randN
是不纯的,因为根据定义,随机数是不纯的。

谢谢你的回答。是的,这只是一个练习。在这种情况下,我最初的完整点解决方案显然比任何无点建议都要好得多。
thunk
在一种迫切需要评估的语言中还有一个优势:它允许配置一些昂贵的计算,但会延迟执行,直到确定需要结果为止。除了副作用之外,这可能是将其纳入Ramda的一个很好的理由。谢谢,我认为您的手动方法很有启发性。你能详细说明你的最后两句话吗?我忽略了这个问题和monads之间的联系。当我通过数学得到它的时候,随机的使它变得不纯,我不明白为什么组成一个空函数会使它变得不纯。我知道什么是单子,问题只是关于这个问题的关系。我猜你的建议是在单子中包含随机效应?@Jonah我已经撤回了我回复的最后一段。IO单子和杂质是不同的概念。当涉及到IO相关的副作用时,两者似乎都有交叉点,仅此而已。抱歉搞混了!第一行代码中的
randN
比最后一行代码中的Rambda实现要好得多。显然,以可读性为代价追求无点风格是一个巨大的错误。我从未声称它更好:)