@@ -34,81 +34,6 @@ isleaf(x) = children(x) === ()
3434
3535children(x) = functor(x)[1 ]
3636
37- function _default_walk(f, x)
38- func, re = functor(x)
39- re(map(f, func))
40- end
41-
42- usecache(:: AbstractDict , x) = isleaf(x) ? anymutable(x) : ismutable(x)
43- usecache(:: Nothing , x) = false
44-
45- @generated function anymutable(x:: T ) where {T}
46- ismutabletype(T) && return true
47- subs = [:(anymutable(getfield(x, $ f))) for f in QuoteNode.(fieldnames(T))]
48- return Expr(:(|| ), subs... )
49- end
50-
51- struct NoKeyword end
52-
53- function fmap(f, x; exclude = isleaf, walk = _default_walk, cache = anymutable(x) ? IdDict() : nothing , prune = NoKeyword())
54- if usecache(cache, x) && haskey(cache, x)
55- return prune isa NoKeyword ? cache[x] : prune
56- end
57- ret = if exclude(x)
58- f(x)
59- else
60- walk(x -> fmap(f, x; exclude, walk, cache, prune), x)
61- end
62- if usecache(cache, x)
63- cache[x] = ret
64- end
65- ret
66- end
67-
68- # ##
69- # ## Extras
70- # ##
71-
72- fmapstructure(f, x; kwargs... ) = fmap(f, x; walk = (f, x) -> map(f, children(x)), kwargs... )
73-
74- function fcollect(x; output = [], cache = Base. IdSet(), exclude = v -> false )
75- # note: we don't have an `OrderedIdSet`, so we use an `IdSet` for the cache
76- # (to ensure we get exactly 1 copy of each distinct array), and a usual `Vector`
77- # for the results, to preserve traversal order (important downstream!).
78- x in cache && return output
79- if ! exclude(x)
80- push!(cache, x)
81- push!(output, x)
82- foreach(y -> fcollect(y; cache= cache, output= output, exclude= exclude), children(x))
83- end
84- return output
85- end
86-
87- # ##
88- # ## Vararg forms
89- # ##
90-
91- function fmap(f, x, ys... ; exclude = isleaf, walk = _default_walk, cache = anymutable(x) ? IdDict() : nothing , prune = NoKeyword())
92- if usecache(cache, x) && haskey(cache, x)
93- return prune isa NoKeyword ? cache[x] : prune
94- end
95- ret = if exclude(x)
96- f(x, ys... )
97- else
98- walk((xy... ,) -> fmap(f, xy... ; exclude, walk, cache, prune), x, ys... )
99- end
100- if usecache(cache, x)
101- cache[x] = ret
102- end
103- ret
104- end
105-
106- function _default_walk(f, x, ys... )
107- func, re = functor(x)
108- yfuncs = map(y -> functor(typeof(x), y)[1 ], ys)
109- re(map(f, func, yfuncs... ))
110- end
111-
11237# ##
11338# ## FlexibleFunctors.jl
11439# ##
0 commit comments