2014-01-25 2 views
10

У меня есть функция, которая выглядит следующим образом:Scala - сочинить функция п раз

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

Я хочу, чтобы вызвать функцию handleOpcode п число раз (скажем, в 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 
Смежные вопросы