Is my rec function tail recursive?

后端 未结 3 1232
既然无缘
既然无缘 2021-01-21 02:04


Is this function tail-recursive ?

let rec rec_algo1 step J = 
    if step = dSs then J
    else
        let a = Array.init (Array2D.length1 M) (fun i ->         


        
3条回答
  •  囚心锁ツ
    2021-01-21 02:30

    You asked how we can formally check this so I'll have a stab. We first have to define what it means for a function to be tail-recursive. A recursive function definition of the form

    let rec f x_1 ... x_n = e
    

    is tail recursive if all calls of f inside e are tail calls - ie. occur in a tail context. A tail context C is defined inductively as a term with a hole []:

    C ::= []
        | e
        | let p = e in C
        | e; C
        | match e with p_1 -> C | ... | p_n -> C
        | if e then C else C
    

    where e is an F# expression, x is a variable and p is a pattern. We ought to expand this to mutually recursive function definitions but I'll leave that as an exercise.

    Lets now apply this to your example. The only call to rec_algo1 in the body of the function is in this context:

    if step = dSs then J
    else
        let a = Array.init (Array2D.length1 M) (fun i -> minby1J i M J)
        let argmin = a|> Array.minBy snd |> fst
        []
    

    And since this is a tail context, the function is tail-recursive. This is how functional programmers eyeball it - scan the body of the definition for recursive calls and then verify that each occurs in a tail context. A more intuitive definition of a tail call is when nothing else is done with the result of the call apart from returning it.

提交回复
热议问题