Functional style early exit from depth-first recursion

前端 未结 3 2045
清歌不尽
清歌不尽 2021-02-08 18:52

I have a question about writing recursive algorithms in a functional style. I will use Scala for my example here, but the question applies to any functional language.

I

3条回答
  •  甜味超标
    2021-02-08 19:34

    The following implements a lazy depth-first search over nodes in a tree.

    import collection.TraversableView
    case class Node[T](label: T, ns: Node[T]*)
    def dfs[T](r: Node[T]): TraversableView[Node[T], Traversable[Node[T]]] =
      (Traversable[Node[T]](r).view /: r.ns) {
        (a, b) => (a ++ dfs(b)).asInstanceOf[TraversableView[Node[T], Traversable[Node[T]]]]
      }
    

    This prints the labels of all the nodes in depth-first order.

    val r = Node('a, Node('b, Node('d), Node('e, Node('f))), Node('c))
    dfs(r).map(_.label).force
    // returns Traversable[Symbol] = List('a, 'b, 'd, 'e, 'f, 'c)
    

    This does the same thing, quitting after 3 nodes have been visited.

    dfs(r).take(3).map(_.label).force
    // returns Traversable[Symbol] = List('a, 'b, 'd)
    

    If you want only leaf nodes you can use filter, and so forth.

    Note that the fold clause of the dfs function requires an explicit asInstanceOf cast. See "Type variance error in Scala when doing a foldLeft over Traversable views" for a discussion of the Scala typing issues that necessitate this.

提交回复
热议问题