0

F# チームのブログ記事で F# テール コールをテストしているときに、コード内の括弧だけが異なるだけで、ほぼ同じコードの結果は同じですが、 ILが異なることがわかりました。

次のコードはコンパイラによって最適化されbr.s IL_0000、IL の最後に表示され、呼び出しはありません。sumSoFar

let rec loopAndSum aList sumSoFar = 
    match aList with
    | [] -> sumSoFar
    | x :: xs -> 
        loopAndSum xs (sumSoFar + x)

loopAndSum [ 1..5 ] 0 
|> printfn "sum: %i"

しかし、その部分はコンパイラによって最適化されておらずcall bla_bla.loopAndSum、IL の終わりに近づいています。

let rec loopAndSum aList sumSoFar = 
    match aList with
    | [] -> sumSoFar
    | x :: xs -> 
        loopAndSum xs sumSoFar + x

loopAndSum [ 1..5 ] 0 
|> printfn "sum: %i"

これらの例は、 を囲む括弧のみが異なりますsumSoFar + xそれをいじって、 .NET Fiddleで IL を見ることができます。

かっこが重要な理由を知っている人はいますか?

4

1 に答える 1

4

関数適用は、どの演算子よりも優先されます。したがって、括弧なしでは、次と同等です。

(loopAndSum xs sumSoFar) + x

したがって、末尾呼び出しではありません。追加は再帰呼び出しの後に実行されます。結果の値が正しいのは偶然です。

于 2015-03-07T20:08:43.327 に答える