Glubs
Glubs

Reputation: 106

Is there a proper functional programming name for this function (f1, f2, val) => f1(f2(val), val);

I came up with this function (f1, f2, val) => f1(f2(val), val) (javascript notation) and it seemed like it would be useful/common for functional programming. I wanted to know if this function already exists and if it does what it's proper name would be.

(an equivalent question would be what is (f1, f2, val) => f1(f2(val)) called? and the equivalent answer would be composition)

Upvotes: 1

Views: 141

Answers (5)

user5536315
user5536315

Reputation:

This is the chain function of the monad API specialized to the function type. The good thing about monads is that you can apply them for any type in a mechanical way and they always work as expected:

// your combinator in curried form with the two first arguments flipped
const chain = g => f => x => f(g(x)) (x);

// 2nd part of the monad interface
const of = x => _ => x;

const add = x => y => x + y;

/* ridiculously complicated Fibonacci algorithm
   just to demonstrate the predictability of monads */

const fib = n =>
  n > 1
    ? chain(of(n - 1)) (w =>
        chain(of(n - 2)) (x =>
          chain(fib(w)) (y =>
            chain(fib(x)) (z =>
              of(y + z)))))
    : of(n);

const main = fib(10);

console.log(
  main()); // 55

Once you have grasped how monads work it isn't so hard anymore to understand the given example for the function type and any example for any type that implements the monad type class.

Upvotes: 0

Matías Fidemraizer
Matías Fidemraizer

Reputation: 64923

It looks like the S combinator variation:

const S = f => g => x => f (x) (g (x))

Probably you might be able to refactor your code to accomodate to S combinator.

Upvotes: 0

qxg
qxg

Reputation: 7036

It's just bind (>>=) operator of function monad.

In Haskell, function is represented as a -> b, which can be considered as an operator (->) takes two parameters and rewritten as (->) a b. We can partial apply (->) with one parameter, (->) a.

(->) a is a functor and monad. As a monad, it's definition is

instance Monad ((->) r) where
    f >>= k = \ r -> k (f r) r

In ramda, it's chain function.

Upvotes: 2

Hitmands
Hitmands

Reputation: 14179

First example looks like a branch/converge function, where the second argument is simply passed as identity.

const a = (f1, f2, val) => f1(f2(val), val);
const b = (f1, f2, val) => R.converge(f1, [f2, R.identity])(val);

const f1 = (a, b) => a + b;
const f2 = (a) => a * 2;

console.log(
  a(f1, f2, 50),
);

console.log(
  b(f1, f2, 50),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js" integrity="sha256-buL0byPvI/XRDFscnSc/e0q+sLA65O9y+rbF+0O/4FE=" crossorigin="anonymous"></script>


Second example is simply a compose function...

const a = (f1, f2, val) => f1(f2(val));
 
const f1 = (a) => a * 2;
const f2 = (a) => a + 100;
 
console.log(
  a(f1, f2, 50),
);
 
console.log(
  R.compose(f1, f2)(50),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js" integrity="sha256-buL0byPvI/XRDFscnSc/e0q+sLA65O9y+rbF+0O/4FE=" crossorigin="anonymous"></script>

Upvotes: 0

customcommander
customcommander

Reputation: 18901

This looks like Ramda's chain method to me:

If second argument is a function, chain(f, g)(x) is equivalent to f(g(x), x).

So:

R.chain(R.append, R.sum)([1, 2, 3]);

is similar to:

R.append(R.sum([1, 2, 3]), [1, 2, 3]);
//=> [1, 2, 3, 6]

Whether the common name for such pattern is chain I am not sure. Functional programming sometimes has impenetrable lingo IMHO.

Upvotes: 0

Related Questions