2017-09-27 3 views
2

私は十分に単純な2つの数を乗算するこの再帰関数を持っています。スカラテール再帰

今、私は末尾再帰関数にそれを回すためにしようとしている、と私はこれを試してみました
def mul(n: Int, m: Int):Int = 
     if(m > 1) n + mul(n, dec(m)) 
     else n 

def mulWithTail(n: Int, m: Int):Int = { 
     @tailrec 
     def iter(result: Int, x: Int):Int = 
      if(x == 0) result 
      else result + iter(result, dec(x)) 
     iter(n, m) 
    } 

私は次のエラーを取得するしかし:

error: could not optimize @tailrec annotated method iter: it contains a recursive call not in tail position

else result + iter(result, dec(x))

質問:このエラーがなぜ発生しているのか説明できますか?私のコードをどのようにリファクタリングすべきですか?

+0

デク()ただ1ところで – Phillip

答えて

7

アキュムレータのように機能する特別なパラメータを追加するだけで、関数の末尾を再帰的にすることができます。このような。

def mul(n: Int, m: Int, acc: Int): Int = 
    if (m > 1) mul(n, m - 1, n + acc) 
    else acc 

あなたは再帰ステップで他の操作を行うが、再帰関数を呼び出してはならない機能の尾の再帰を作ること。コードサンプルでは、​​再帰ステップで追加を実行しています。

  • n + mul(n, dec(m))

  • result + iter(result, dec(x))

+0

によってデクリメントあなたは、この追加のパラメータを追加すること末尾再帰なりますどのように説明できますか? – Phillip

+0

説明を含むように編集されました。 – Micho

+0

ありがとう、今の意味がある! – Phillip