2
私が知っている関数はテール再帰的です。しかし、私が定義する方法のために、コンパイラは、非テール位置で再帰呼び出しを持つ関数について不満を抱いています。これが関数です。このテール再帰的なスカラ関数に注釈を付ける方法
@tailrec
def travel: (Int, List[Char]) => Int = {
case (n, Nil) => n
case (n, '~' :: sls) => travel(0, sls)
case (n, '^' :: sls) => travel(max(n-1,0), sls)
case (n, '>' :: sls) => travel(n+1, sls)
case (_, s :: sls) => throw new IllegalArgumentException("Illegal selector '" + s + "'")
}
私はこのようにそれを書けば、それが正常に動作します
error: could not optimize @tailrec annotated method travel: it contains a recursive call not in tail position
def travel: (Int, List[Char]) => Int = {
を取得します。
@tailrec
def travel(n:Int, l:List[Char]): Int = (n,l) match {
case (n, Nil) => n
case (n, '~' :: sls) => travel(0, sls)
case (n, '^' :: sls) => travel(max(n-1,0), sls)
case (n, '>' :: sls) => travel(n+1, sls)
case (_, s :: sls) => throw new IllegalArgumentException("Illegal selector '" + s + "'")
}
私はそれがdef: (Input) => Output = {}
型宣言スタイルと関係があると思います。ネストされたマッチやタプルのマッチを書くよりもきれいに見えるので、私はそれを使います。
私は「@ tailrec」アノテーションを無名関数に追加できますか?* – paradigmatic
@paradigmatic - それは別の質問ですが、良いものです。アノテーションではありませんが、無名関数が末尾再帰呼び出しを行う方法です。 (独自の 'apply'メソッドを見ることはできません)。 –