-
-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make fmap(f, x, y)
useful
#37
Changes from 8 commits
e74a277
133032e
7bbfa31
4adbcf1
7ab2efd
ff39b09
2e71bb8
2522f67
6e0b7bc
a057d08
2d2c40e
38b2aec
077d6e5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ functor(T, x) = (), _ -> x | |
functor(x) = functor(typeof(x), x) | ||
|
||
functor(::Type{<:Tuple}, x) = x, y -> y | ||
functor(::Type{<:NamedTuple}, x) = x, y -> y | ||
functor(::Type{<:NamedTuple{L}}, x) where L = NamedTuple{L}(map(s -> getproperty(x, s), L)), identity | ||
|
||
functor(::Type{<:AbstractArray}, x) = x, y -> y | ||
functor(::Type{<:AbstractArray{<:Number}}, x) = (), _ -> x | ||
|
@@ -43,12 +43,11 @@ function _default_walk(f, x) | |
re(map(f, func)) | ||
end | ||
|
||
function fmap(f, x; exclude = isleaf, walk = _default_walk, cache = IdDict()) | ||
haskey(cache, x) && return cache[x] | ||
y = exclude(x) ? f(x) : walk(x -> fmap(f, x, exclude = exclude, walk = walk, cache = cache), x) | ||
cache[x] = y | ||
const INIT = Base._InitialValue() # sentinel value for keyword not supplied | ||
|
||
return y | ||
function fmap(f, x; exclude = isleaf, walk = _default_walk, cache = IdDict(), prune = INIT) | ||
haskey(cache, x) && return prune === INIT ? cache[x] : prune | ||
cache[x] = exclude(x) ? f(x) : walk(x -> fmap(f, x; exclude, walk, cache, prune), x) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To use keywords like this, this package cannot claim to support Julia 1.0. At present it is only tested on 1.5+. Maybe we should just move to 1.6? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We already have on CI, might as well make it official. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what repo I was looking at, because I just checked back and it's 1.5 still. Do we need to cut a breaking release for minimum version bumps like this again? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's 1.0 here: https://github.com/FluxML/Functors.jl/blob/master/Project.toml#L7 Tests do in fact pass on 1.0, for Functors v0.2.7, despite the lack of CI. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And, people say not to do this on a patch release, because it closes the door on a bugfix-for-1.0 release. Do we care? We may also need a breaking release for #33, and to make the cache not used on isbits arguments. We could gang these together. |
||
end | ||
|
||
### | ||
|
@@ -74,27 +73,16 @@ end | |
### Vararg forms | ||
### | ||
|
||
function fmap(f, x, dx...; cache = IdDict()) | ||
haskey(cache, x) && return cache[x] | ||
cache[x] = isleaf(x) ? f(x, dx...) : _default_walk((x...) -> fmap(f, x..., cache = cache), x, dx...) | ||
function fmap(f, x, ys...; exclude = isleaf, walk = _default_walk, cache = IdDict(), prune = INIT) | ||
haskey(cache, x) && return prune === INIT ? cache[x] : prune | ||
cache[x] = exclude(x) ? f(x, ys...) : walk((xy...,) -> fmap(f, xy...; exclude, walk, cache, prune), x, ys...) | ||
end | ||
|
||
function functor_tuple(f, x::Tuple, dx::Tuple) | ||
map(x, dx) do x, x̄ | ||
_default_walk(f, x, x̄) | ||
end | ||
end | ||
functor_tuple(f, x, dx) = f(x, dx) | ||
functor_tuple(f, x, ::Nothing) = x | ||
|
||
function _default_walk(f, x, dx) | ||
function _default_walk(f, x, ys...) | ||
func, re = functor(x) | ||
map(func, dx) do x, x̄ | ||
# functor_tuple(f, x, x̄) | ||
f(x, x̄) | ||
end |> re | ||
yfuncs = map(y -> functor(typeof(x), y)[1], ys) | ||
re(map(f, func, yfuncs...)) | ||
end | ||
_default_walk(f, ::Nothing, ::Nothing) = nothing | ||
|
||
### | ||
### FlexibleFunctors.jl | ||
|
@@ -112,9 +100,7 @@ function makeflexiblefunctor(m::Module, T, pfield) | |
func = NamedTuple{pfields}(map(p -> getproperty(x, p), pfields)) | ||
return func, re | ||
end | ||
|
||
end | ||
|
||
end | ||
|
||
function flexiblefunctorm(T, pfield = :params) | ||
|
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe less opaque to just define
struct NoPrune end
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can do. Are you OK with the interface being that the absence of this keyword is how you turn this off? That's how
init
often works; and here, the values you might use for "don't prune" likefalse
ornothing
are all reasonable choices for the value to use during pruning.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code is weird to me, but the API makes sense. I'm happy.