Home > other >  List of functions as parameter of function (R)
List of functions as parameter of function (R)

Time:01-22

I have a problem: I need to run the same function over and over, but with different parameters, inside another function. How can I implement it straightforwardly, because the manual method I'm doing currently produces very much code and makes my code unreadable?

Pseudocode:

internal_func <- function(x, y, z)

external_func <- function(list_of_functions) {
   # do some stuff

   for(i in 1:length(list_of_functions)){
      # evaluate the internal function and save the results in a matrix
   }

   # do some more stuff
   return(stuff)
}

# run 1
# generate list of internal_func with varying x and pass it to external_func

# run 2
# generate list of internal_func with varying y and pass it to external_func

# run 3
# generate list of internal_func with varying y and pass it to external_func

Thank you in advance!

CodePudding user response:

just guessing at what might be useful to you; finding it hard to guess from your pseudo code... anyway here is some small code that manufactures a list of functions each with a different parameter (that varies how many numbers they will generate); these are passed to an outerfunction that operates on their results


library(purrr)

my_partials <- map(1:5,\(x_)
    partial(.f=rnorm,n=x_))

outerfunc <- function(func){
  round(func(),0)
}
map(my_partials,outerfunc)
[[1]]
[1] 1

[[2]]
[1]  1 -1

[[3]]
[1] 0 0 0

[[4]]
[1]  1  0  0 -1

[[5]]
[1] -1  2  1  1  0

CodePudding user response:

I'm not quite sure I understood properly your question, but as I understand it is a good way to explain Applicative functors, so I wrote some code with Scala.

Applicative functors have ap function with the following signature:

def ap[A, B](ff: F[A => B])(fa: F[A]): F[B]

F being a functor, like List, in fact List is an applicative functor!

So we can write:

prelude:

import cats.implicits._

type X = Int
type Y = Int
type Z = Int
type R = Int

cats gives us the applicative instance for List, and the type aliases so we have nice code next:

val f: X => Y => Z => R = x => y => z => x   y   z
val g: X => Y => Z => R = x => y => z => x - y - z

val internal_func = List(f, g)

// generate list of internal_func with varying x
((internal_func ap List(1, 2, 3)) ap List(5)) ap List(40)
// res36: List[R] = List(46, 47, 48, -44, -43, -42)

// generate list of internal_func with varying y
((internal_func ap List(10)) ap List(3, 4, 5)) ap List(2)
// res37: List[R] = List(15, 16, 17, 5, 4, 3)

// generate list of internal_func with varying z
((internal_func ap List(20)) ap List(3)) ap List(4,5,6)
// res38: List[R] = List(27, 28, 29, 13, 12, 11)

The result is not so clean, I'm sure it could be improved. But the idea is the first 3 entries are f(x, y, z) varying one variable, and the second 3 are g(x, y, z) varying one variable.

It can even be done in just one execution setting all variations in together, but the reading is not so clear for this explanation.

I hope it fits your question! The inline ap would be replacing your for loop so you can still do stuff before and after.

  • Related