F # using battery while still getting an exception

In the next function, I tried to set up tail recursion with battery. However, I get exceptions that make me think that the way I configure my function is to correctly allow tail recursion.

//F# attempting to make a tail recursive call via accumulator
let rec calc acc startNum =
    match startNum with
    | d when d = 1      -> List.rev (d::acc)
    | e when e%2 = 0    -> calc (e::acc) (e/2)
    | _                 -> calc (startNum::acc) (startNum * 3 + 1)

I understand that using it accwill allow the compiler to see that there is no need to store all the frames of the stack for each recursive call, since it can stuff the result of each pass into acc and return from each frame. Obviously, I don’t understand how to use the battery value correctly, so the compiler makes tail calls.

+3
source share
2

, , , , VS ( ). , VS , .

, , , , , , , , , , ,

'Qaru Exception: a recursive function does not 
tail call by default when in debug mode'
+3

, .NET Framework . , Reflector while(true), , F # :

[CompilationArgumentCounts(new int[] { 1, 1 })]
public static FSharpList<int> calc(FSharpList<int> acc, int startNum)
{
    while (true)
    {
        int num = startNum;
        switch (num)
        {
            case 1:
            {
                int d = num;
                return ListModule.Reverse<int>(FSharpList<int>.Cons(d, acc));
            }
        }
        int e = num;
        if ((e % 2) == 0)
        {
            int e = num;
            startNum = e / 2;
            acc = FSharpList<int>.Cons(e, acc);
        }
        else
        {
            startNum = (startNum * 3) + 1;
            acc = FSharpList<int>.Cons(startNum, acc);
        }
    }
}

( F # 2.0, , ). ? ( .) , , , .

+1

Source: https://habr.com/ru/post/1773347/


All Articles