uehaj's blog

Grな日々 - GroovyとかGrailsとかElmとかRustとかHaskellとかReactとかFregeとかJavaとか -

Closure#trampoline()続き

昨日trampoline()について書きましたが、今日はtrampoline()で相互再帰もできますという話。まずはtrampoilne()使わないバージョン。

oddp = { n ->
  if (n==0) {
      false
  }
  else evenp(n -1)
}

evenp = { n ->
  if (n == 0) {
    true
  }
  else oddp(n - 1)
}

println oddp(30000) // ==>StackOverflowError
println evenp(30000) // ==>StackOverflowError

続いてtrampoline()バージョン。

oddp = { n ->
  if (n==0) {
      false
  }
  else evenp.trampoline(n -1)
}

evenp = { n ->
  if (n == 0) {
    true
  }
  else oddp.trampoline(n - 1)
}

assert oddp.trampoline()(30000) == false
assert evenp.trampoline()(30000) == true

こんな感じ。相互再帰の場合、「callをtrampolineに置き換える」という話じゃすまなくなりますね。うーん。