1+ """
2+ AbstractWalk
3+
4+ Any walk for use with [`fmap`](@ref) should inherit from this type.
5+ A walk subtyping `AbstractWalk` must satisfy the walk function interface:
6+ ```julia
7+ struct MyWalk <: AbstractWalk end
8+
9+ function (::MyWalk)(recurse, x, ys...)
10+ # implement this
11+ end
12+ ```
13+ The walk function is called on a node `x` in a Functors tree.
14+ It may also be passed associated nodes `ys...` in other Functors trees.
15+ The walk function recurses further into `(x, ys...)` by calling
16+ `recurse` on the child nodes.
17+ The choice of which nodes to recurse and in what order is custom to the walk.
18+ """
119abstract type AbstractWalk end
220
21+ """
22+ AnonymousWalk(walk_fn)
23+
24+ Wrap a `walk_fn` so that `AnonymousWalk(walk_fn) isa AbstractWalk`.
25+ This type only exists for backwards compatability and should be directly used.
26+ Attempting to wrap an existing `AbstractWalk` is a no-op (i.e. it is not wrapped).
27+ """
28+ struct AnonymousWalk{F} <: AbstractWalk
29+ walk:: F
30+ end
31+ # do not wrap an AbstractWalk
32+ AnonymousWalk (walk:: AbstractWalk ) = walk
33+
34+ (walk:: AnonymousWalk )(recurse, x, ys... ) = walk. walk (recurse, x, ys... )
35+
36+ """
37+ DefaultWalk()
38+
39+ The default walk behavior for Functors.jl.
40+ Walks all the [`Functors.children`](@ref) of trees `(x, ys...)` based on
41+ the structure of `x`.
42+ The resulting mapped child nodes are restructured into the type of `x`.
43+
44+ See [`fmap`](@ref) for more information.
45+ """
346struct DefaultWalk <: AbstractWalk end
447
548function (:: DefaultWalk )(recurse, x, ys... )
@@ -8,10 +51,27 @@ function (::DefaultWalk)(recurse, x, ys...)
851 re (map (recurse, func, yfuncs... ))
952end
1053
54+ """
55+ StructuralWalk()
56+
57+ A structural variant of [`Functors.DefaultWalk`](@ref).
58+ The recursion behavior is identical, but the mapped children are not restructured.
59+
60+ See [`fmapstructure`](@ref) for more information.
61+ """
1162struct StructuralWalk <: AbstractWalk end
1263
1364(:: StructuralWalk )(recurse, x) = map (recurse, children (x))
1465
66+ """
67+ ExcludeWalk(walk, fn, exclude)
68+
69+ A walk that recurses nodes `(x, ys...)` according to `walk`,
70+ except when `exclude(x)` is true.
71+ Then, `fn(x, ys...)` is applied instead of recursing further.
72+
73+ Typically wraps an existing `walk` for use with [`fmap`](@ref).
74+ """
1575struct ExcludeWalk{T, F, G} <: AbstractWalk
1676 walk:: T
1777 fn:: F
2383
2484struct NoKeyword end
2585
86+ """
87+ CachedWalk(walk[; prune])
88+
89+ A walk that recurses nodes `(x, ys...)` according to `walk` and storing the
90+ output of the recursion in a cache indexed by `x` (based on object ID).
91+ Whenever the cache already contains `x`, either:
92+ - `prune` is specified, then it is returned, or
93+ - `prune` is unspecified, and the previously cached recursion of `(x, ys...)`
94+ returned.
95+
96+ Typically wraps an existing `walk` for use with [`fmap`](@ref).
97+ """
2698struct CachedWalk{T, S} <: AbstractWalk
2799 walk:: T
28100 prune:: S
@@ -40,6 +112,15 @@ function (walk::CachedWalk)(recurse, x, ys...)
40112 end
41113end
42114
115+ """
116+ CollectWalk()
117+
118+ A walk that recurses into a node `x` via [`Functors.children`](@ref),
119+ storing the recursion history in a cache.
120+ The resulting ordered recursion history is returned.
121+
122+ See [`fcollect`](@ref) for more information.
123+ """
43124struct CollectWalk <: AbstractWalk
44125 cache:: Base.IdSet{Any}
45126 output:: Vector{Any}
0 commit comments