2016-04-02 41 views
3

我想在R中定义一个函数,它将一个函数作为参数并将其应用两次到它的参数。在R中应用两次函数

例如

x <- function twice (plusone 1) 

3 

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

如何在R中做到这一点?

回答

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

可如果你从哈斯克尔来概括为

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

,你就会明白,钻营容易R中做的一样好。这个答案也比@ baptiste更完整。看到最后一句话

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 

值得注意的是,如果n是程序中的一个动态的变量,它可能是0或负数。 repeatf仍然会在这些情况下操作

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

@巴蒂斯特的解决方案将失败

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

显然对于n <1我的版本会失败,但我)被真正定义/有用?; ii)我根本没有考虑这些情况。如果(n <= 0)x else,nice < - 函数(f,n,x)调用(f,n-1,f(x))'“修复”它平凡。未指定的角落案例也会导致您的解决方案失败;以'?Recall'为例进行重命名。 – baptiste

+0

@baptiste当然有一个总功能是非常有用的;一个适用于指定类型的所有输入。想象一下,我们在哪里用变量而不是静态输入来称呼你的“nice”函数。如果'n'由于其他计算而被分配了'0',那么它很容易中断。例如'nice(f,somefunc(),2)'where'somefunc()'返回'0'。我不认为这是一个特例。是的,我同意这个解决方案非常简单,所以你一定要这么做。 – naomik

+0

@baptiste您能否演示一下'repeatf'的这个实现是如何破解的?我看不出重命名的东西会导致破损。来自'?Recall'的 – naomik