Function composition assigned to %@% operator in R

Viewed 166

In mathematics, we use superpositions of functions often. Obviously, we can define superpositions of any number of functions, e.g., (h∘g∘f)(x)(h∘g∘f)(x). My question is following -> How to define a superposition binary operator %@% ?

Let's start with a simple example.

sin %@% -pi/4

The above expression returns the value sin(−π/4) when evaluated. I would like to get an implementation of the %@% operator which allows for superposing any finite number of functions like in the following example (please see below). Could you please provide me with the solution without any additional R-packages? It will be very helpful.

tanh %@% exp %@% abs %@% sin %@% -pi/4

2 Answers

The following function adapts the code in this answer to a similar question.

`%@%` <- function(f, g) {
  if(is.function(g))
    function(...) f(g(...))
  else f(g)
}

sin %@% (-pi/4)
#[1] -0.7071068
(sin %@% cos)(-pi/4)
#[1] 0.6496369

Anonymous functions must be put between brackets {.}.

pow2 <- function(x) x^2
(pow2 %@% sin)(-pi/4)
#[1] 0.5
({function(x) x^2} %@% sin)(-pi/4)
#[1] 0.5

I don't know whether it is appropriate, but my first intention would be the following:

`%@%` <- function(f,g) {
  if(is.function(f) && is.function(g)) {
    #both functions, composition as usual
    return(function(...) {f(g(...))} )
  }
  if(!is.function(f)) {
    #f is no function, hence a constant value, return it.
    return(f)
  }
  if(is.function(f) && !is.function(g)) {
    #f is function, g not, hence g is the argumemnt to f
    return(f(g))
  }
}

Some test:

sq <- function(x) x^2
sq %@% sq %@% 5 #625
base::identity %@% base::identity %@% 5 #5
exp %@% log %@% 5 #5
5 %@% sin #5

tanh %@% exp %@% abs %@% sin %@% -pi/4 #0.1903985
Related