Writing a parameterless function in Ramda in a dot-free style?

Consider the working code below:

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 is a function that takes a number and returns an RNG, which when called returns a random int in the range [0, N-1]. So this is a factory for specific RNGs.

I used ramda.js and studied the theory of functional programming, and my question is: is it possible to rewrite randN in free style using ramda?

For example, I could write:

 var badAttempt = pipe(multiply(Math.random()), Math.floor) 

This will satisfy the dot-free requirement, but cannot behave the same as randN : calling badAttempt(10) simply returns a single random number from 1 to 10, not a function that generates a random number from 1 to 10 when called.

I was not able to find a combination of ramda functions that allows me to rewrite in style without restriction. I can’t say whether this is just a failure on my part or something special in using random , which violates referential transparency and therefore may not be compatible with a dotless style.

Update

my little variation of the solution, after a discussion with Denys:

 randN = pipe(always, of, append(Math.random), useWith(pipe(multiply, Math.floor)), partial(__,[1,1])) 
+5
source share
3 answers

 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> 
+1
source

This will help with an extra function to abstract the function to re-evaluate its arguments every time it is called.

 thunk = fn => R.curryN(fn.length, (...args) => () => fn(...args)) 

The sole purpose of this function is to cause some side effect in the given function fn .

Once we have the thunk function, we can define randN as follows:

 randN = thunk(R.pipe(SS(R.multiply, Math.random), Math.floor)) R.times(randN(10), 5) // eg [1, 6, 9, 4, 5] 

Note: SS here is the S combinator from Sanctuary , which does the same as R.converge(multiply, [Math.random, identity]) .

However, I recommend using a dotless solution if it really improves the readability of the function.

+3
source

I do not know if it is useful to study functional programming using a specific library, because the characteristics of lib and the functional paradigm will inevitably mix. In practice, however, Ramda is incredibly useful. It bridges the gap between imperative reality and functional Fantasy Land in Javascript: D

The manual approach is used here:

 // 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()); 

It is worth noting that randN is unclean since random numbers are unclean by definition.

+2
source

Source: https://habr.com/ru/post/1245661/


All Articles