2014-01-25 57 views
10

我有一个功能,看起来像这样:斯卡拉 - 构建功能N次

def emulate: (Cpu => Cpu) => (Cpu => Cpu) = render => { 
    handleOpcode andThen 
    handleTimers andThen 
    handleInput andThen 
    debug   andThen 
    render 
} 

我要打电话的次数handleOpcode功能n个(比如说10次)。在Haskell我可以写一个函数,像这样:

ntimes n f = foldr (.) id (replicate n f) 

但在Scala中,我不知道我怎么会写。我试过了:

def nTimes(n: Int, f: => Any) = { 
    val l = List.fill(n)(f) 
    l.foldRight(identity[Function]){ (x, y) => y.andThen(x) } 
} 

但是类型都是错的。

有没有简单的方法来实现这一点?理想情况下,无需创建自己的功能。也许在斯卡拉斯有一些东西?

+2

那么'f'不是那里的函数,它只是一个非严格的'Any',所以类型都是错的并不奇怪。为什么你不像Haskell那样开始写类型? –

回答

13

你可以使用Function.chain方法:

scala> val add1 = (x:Int) => x+1 
add1: Int => Int = <function1> 

scala> val add5 = Function.chain(List.fill(5)(add1)) 
add5: Int => Int = <function1> 

scala> add5(5) 
res1: Int = 10 
5

我不知道是否有通过Scalaz提供的东西更优雅,但如果你按摩的类型有点您的解决方案应该可以正常工作:

def nTimes[T](n: Int, f: T=>T) = { 
    val l = List.fill(n)(f) 
    l.foldRight(identity: T=>T){ (x, y) => y.andThen(x) } 
} 

// example 
def inc(i: Int) = i+1 

nTimes(5, inc)(0) 
// => 5