Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointfree dynamic function composition

I'm trying to refactor this function to be pointfree.

function siblings(me) {
  return R.pipe(family, R.reject(equalsMe(me)))(me);
}

I'd like to pass me to a function down the pipe along with the value that family returns.

Tried a few things with R.useWith or R.converge with R.identity or R.__ (not even sure if I should be using that) but found nothing to work.

like image 603
AKG Avatar asked Apr 22 '21 02:04

AKG


People also ask

What is point-free programming in Python?

Tacit programming (point-free programming) is a programming paradigm in which a function definition does not include information regarding its arguments, using combinators and function composition [...] instead of variables. Point-free ( sum doesn't have any explicit arguments - it's just a fold with + starting with 0):

What does point-free style mean?

Point-free style means that the arguments of the function being defined are not explicitly mentioned, that the function is defined through function composition. and if you want to combine these two functions to one that calculates x*x+1, you can define it "point-full" like this: The point-free alternative would be not to talk about the argument x:

How to find the composition of function f with itself?

Suppose f is a function, then the composition of function f with itself will be Let us understand this with an example: Example: If f (x) = 3x2, then find (f∘f) (x). Q.1: If f (x) = 2x and g (x) = x+1, then find (f∘g) (x) if x = 1.

What are the properties of composition of functions?

Few more properties are: 1 The function composition of one-to-one function is always one to one. 2 The function composition of two onto function is always onto 3 The inverse of the composition of two functions f and g is equal to the composition of the inverse of both the functions, such as (f ∘ g) -1 = ( g -1 ...


3 Answers

I'd also suggest using R.converge and swapping R.reject(equalsMe(me)) with R.without(me)

const withFamily = R.always(['fratello', 'sorella', 'io']);

const siblingsOf = R.converge(R.without, [
  R.identity,
  withFamily,
]);

console.log(
  siblingsOf('io'),
);

console.log(
  siblingsOf('sorella'),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js" integrity="sha512-3sdB9mAxNh2MIo6YkY05uY1qjkywAlDfCf5u1cSotv6k9CZUSyHVf4BJSpTYgla+YHLaHG8LUpqV7MHctlYzlw==" crossorigin="anonymous"></script>
like image 183
Hitmands Avatar answered Nov 10 '22 01:11

Hitmands


If I understand correctly family is a function that takes a person and returns a list of family members (including that person) e.g.

family(2);
//=> [1, 2, 3]

Then you want to create a function siblings which takes a person and returns only their siblings e.g.

siblings(2);
//=> [1, 3]

Personally I think your function would read slightly better if it was written this way:

const siblings = me => reject(equals(me), family(me));

siblings(2);
//=> [1, 3]

If you really wanted a pointfree version of it, you could use converge but I really don't think it is any better:

const siblings = converge(reject, [unary(equals), family]);
like image 43
customcommander Avatar answered Nov 10 '22 01:11

customcommander


If you're using R.without (as suggested in Hitmands answer), you can use R.chain with a flipped R.without:

chain(flip(without), withFamily);

Because chain(f, g)(x) is equivalent to f(g(x), x):

chain(flip(without), withFamily)(me)

equals to:

flippedWithout(withFamily(me), me)

Example:

const { always, chain, flip, without } = R;

const withFamily = always(['fratello', 'sorella', 'io']);

const siblingsOf = chain(flip(without), withFamily);

console.log(
  siblingsOf('io'),
);

console.log(
  siblingsOf('sorella'),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js" integrity="sha512-3sdB9mAxNh2MIo6YkY05uY1qjkywAlDfCf5u1cSotv6k9CZUSyHVf4BJSpTYgla+YHLaHG8LUpqV7MHctlYzlw==" crossorigin="anonymous"></script>
like image 41
Ori Drori Avatar answered Nov 10 '22 01:11

Ori Drori