Tail-recursion on trees

后端 未结 2 1862
借酒劲吻你
借酒劲吻你 2020-12-03 19:41

I have a data structure,

datatype \'a tree = Leaf | Branch of \'a tree * \'a * \'a tree

and I want to write a function that traverses this tr

相关标签:
2条回答
  • 2020-12-03 20:35

    Like @seanmcl writes, the systematic way to convert a function to be tail-recursive is to use continuation-passing style.

    After that you probably want to reify your continuations and use a more concrete data type, like a list for instance:

    fun treefoldL f init tree =
        let fun loop Leaf acc [] = acc
              | loop Leaf acc ((x, right) :: stack) =
                loop right (f(x,acc)) stack
              | loop (Branch (left, x, right)) acc stack =
                loop left acc ((x, right) :: stack)
        in  loop tree init [] end
    
    0 讨论(0)
  • 2020-12-03 20:43

    You can achieve a tail-recursive treefold using continuation-passing style:

    fun treefold1 f Leaf acc k = k acc
      | treefold1 f (Branch (left, a, right)) acc k =
        treefold1 f left acc (fn x => treefold1 f right (f(a, x)) k)
    
    fun treefold f t b = treefold1 f t b (fn x => x)
    

    For example:

    fun sumtree t = treefold op+ t 0
    
    val t1 = Branch (Branch(Leaf, 1, Leaf), 2, Branch (Leaf, 3, Leaf))
    
    val n = sumtree t1
    

    results in n = 6 as expected.

    0 讨论(0)
提交回复
热议问题