Point-free version of g(f(x)(y))

133 Views Asked by At

Is there a way to express the following in point-free form:

g(f(x)(y))

It is not a common 'combinator' as far as I can see, though there are perhaps different ways to express it? I am working in Javascript with Ramda.

2

There are 2 best solutions below

9
Ori Drori On BEST ANSWER

I can't think of a readable way to create this combinator in a point-free form. However, since the introduction of arrow functions to JS it's pretty easy to create readable combinators. You can also curry them using Ramda's R.curry, instead of manually curry them (f => g => x => y => g(f(x)(y))):

const { curry, on, identity, multiply, add } = R

const combinator = curry((f, g, x, y) => g(f(x)(y)))

const square = n => n * n;

const squareAddition = combinator(add, square)

const result = squareAddition(1, 2)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js" integrity="sha512-t0vPcE8ynwIFovsylwUuLPIbdhDj6fav2prN9fEu/VYBupsmrmk9x43Hvnt+Mgn2h5YPSJOk7PMo9zIeGedD1A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

2
Mulan On

Here's a point-free comp2 -

// comp : ('b -> 'result) -> ('a -> 'b) -> ('a -> 'result)
const comp = f => g =>
  x => f(g(x))

// comp2 : ('c -> 'result) -> ('a -> 'b -> 'c) -> ('a -> 'b -> 'result)
const comp2 =
  comp(comp)(comp)

// square : number -> number
const square = x =>
  x * x

// add : number -> number -> number
const add = x => y =>
  x + y
 
// addThenSquare : number -> number -> number 
const addThenSquare =
  comp2(square)(add)
  
console.log(addThenSquare(3)(2))
// 25 : number

Sure it's point-free and it works, but maybe this comp2 is more suitable for you -

// comp2 : ('c -> 'd) -> ('a -> 'b -> 'c) -> ('a -> 'b -> 'd)
const comp2 = f => g =>
  a => b => f(g(a)(b))

Here are comp3, comp4, and comp5 if you think you need them -

// comp3 : ('d -> 'result) -> ('a -> 'b -> 'c -> 'd) -> ('a -> 'b -> 'c -> 'result)
const comp3 =
  comp(comp)(comp2)

// comp4 : ('e -> 'result) -> ('a -> 'b -> 'c -> 'd -> 'e) -> ('a -> 'b -> 'c -> 'd -> 'result)
const comp4 =
  comp(comp)(comp3)

// comp5 : ('f -> 'result) -> ('a -> 'b -> 'c -> 'd -> 'e -> 'f) -> ('a -> 'b -> 'c -> 'd -> 'e -> 'result)
const comp5 =
  comp(comp)(comp4)