2016-04-02 15 views
3

Ich möchte eine Funktion in R definieren, die als Argument eine Funktion nimmt und sie zweimal auf ihre Argumente anwendet.Anwenden einer Funktion zweimal in R

Zum Beispiel

x <- function twice (plusone 1) 

3 

In Haskell it is done by twice f = \x -> f (f x) 

.

Wie geht das in R?

Antwort

7
twice <- function(f, x) f(f(x)) 
twice(function(x) x+1, 1) 
# 3 

die als

nice <- function(f, n, x) if(n==1) f(x) else Recall(f, n-1, f(x))  
nice(function(x) x+1, 2, 1) 
3

verallgemeinert werden können, wenn Sie von Haskell anreisen, werden Sie erkennen, dass currying einfach ist, wie auch in R zu tun. Diese Antwort ist auch vollständiger als @ Baptistes. Siehe die letzte Bemerkung

repeatf <- 
    function (n) function (f) function (x) 
    if (n<=0) x else repeatf (n-1) (f) (f(x)) 

once <- repeatf (1) 
twice <- repeatf (2) 
thrice <- repeatf (3) 

square <- function (x) x * x 
once (square) (2) # 4 
twice (square) (2) # 16 
thrice (square) (2) # 256 

Bemerkenswert, wenn n eine dynamische Variable in Ihrem Programm ist, es möglicherweise 0 oder eine negative Zahl sein könnte. repeatf wird in den Fällen,

repeatf (0) (square) (2) # 2 
repeatf (-3) (square) (2) # 2 

@ Baptistes Lösung wäre nicht mit

nice(square, 0, 2) # Error: evaluation nested too deeply: infinite recursion/options(expressions=)? 
nice(square, -3, 2) # Error: evaluation nested too deeply: infinite recursion/options(expressions=)? 
+0

offensichtlich meine Version für n versagt <1, aber ich arbeiten immer noch), dass wirklich definiert/nützlich ?; ii) Ich habe diese Fälle einfach nicht berücksichtigt. 'nice <- function (f, n, x) wenn (n <= 0) x else Recall (f, n-1, f (x))" "behebt es trivial. Ihre Lösung schlägt auch in unangegebenen Fällen fehl; nehmen Sie das Beispiel der Umbenennung in '? Recall'. – baptiste

+0

@baptiste natürlich ist es wirklich nützlich, eine Gesamtfunktion zu haben; eine, die für alle Eingänge des angegebenen Typs funktioniert. Stellen Sie sich vor, wo wir Ihre "nette" Funktion mit Variablen anstatt mit statischen Eingaben aufrufen. Wenn "n" als Ergebnis einer anderen Berechnung "0" zugewiesen wird, würde es sehr leicht brechen. Zum Beispiel 'nice (f, somefunc(), 2)' wobei 'somefunc()' '' 'zurückgibt. Ich denke nicht, dass das ein Eckfall ist. Und ja, ich stimme zu, dass die Lösung unglaublich einfach ist, also sollten Sie es auf jeden Fall tun. – naomik

+0

@baptiste Können Sie bitte demonstrieren, wie diese Implementierung von 'repeatf' bricht? Ich kann nicht sehen, wie das Umbenennen etwas Bruch verursachen würde. – naomik

Verwandte Themen