Accessors.jl
Accessors.jl copied to clipboard
Is `Elements` supposed to be working with `delete`?
Hi, the same optics I'm using for modification
❯ using Accessors, AccessorsExtra
❯ x = Dict(
"a" => (
(1),
(2),
(3)
)
)
Dict{String, Tuple{Int64, Int64, Int64}} with 1 entry:
"a" => (1, 2, 3)
❯ modify(string, x, @optic _["a"])
Dict{String, Any} with 1 entry:
"a" => "(1, 2, 3)"
❯ modify(string, x, @optic _["a"][∗])
Dict{String, Tuple{Any, Any, Any}} with 1 entry:
"a" => ("1", "2", "3")
❯ modify(string, x, @optic _["a"][∗][∗])
Dict{String, Tuple{Any, Any, Any}} with 1 entry:
"a" => ("1", "2", "3")
do not work with deletion
❯ delete(x, @optic _["a"])
Dict{String, Tuple{Int64, Int64, Int64}}()
❯ delete(x, @optic _["a"][∗])
ERROR: MethodError: no method matching delete(::Tuple{Int64, Int64, Int64}, ::Elements)
The function `delete` exists, but no method is defined for this combination of argument types.
Closest candidates are:
delete(::Tuple, ::IndexLens{<:Tuple{AbstractVector}})
@ AccessorsExtra ~/.julia/packages/AccessorsExtra/GMk8B/src/AccessorsExtra.jl:172
delete(::Tuple, ::PropertyLens{field}) where field
@ Accessors ~/.julia/packages/Accessors/C574d/src/optics.jl:406
delete(::Tuple, ::IndexLens)
@ Accessors ~/.julia/packages/Accessors/C574d/src/optics.jl:428
...
Stacktrace:
[1] (::Accessors.var"#5#6"{ComposedFunction{Elements, IndexLens{Tuple{String}}}})(inner_obj::Tuple{Int64, Int64, Int64})
@ Accessors ~/.julia/packages/Accessors/C574d/src/optics.jl:223
[2] _modify
@ ~/.julia/packages/Accessors/C574d/src/optics.jl:218 [inlined]
[3] modify
@ ~/.julia/packages/Accessors/C574d/src/optics.jl:198 [inlined]
[4] delete(obj::Dict{String, Tuple{Int64, Int64, Int64}}, optic::ComposedFunction{Elements, IndexLens{Tuple{String}}})
@ Accessors ~/.julia/packages/Accessors/C574d/src/optics.jl:222
[5] top-level scope
@ REPL[11]:1
❯ delete(x, @optic _["a"][∗][∗])
ERROR: MethodError: no method matching delete(::Int64, ::Elements)
The function `delete` exists, but no method is defined for this combination of argument types.
Closest candidates are:
delete(::Any, ::typeof(basename))
@ Accessors ~/.julia/packages/Accessors/C574d/src/functionlenses.jl:127
delete(::Any, ::typeof(last))
@ Accessors ~/.julia/packages/Accessors/C574d/src/functionlenses.jl:5
delete(::Any, ::typeof(first))
@ Accessors ~/.julia/packages/Accessors/C574d/src/functionlenses.jl:4
...
Stacktrace:
[1] (::Accessors.var"#5#6"{ComposedFunction{Elements, Elements}})(inner_obj::Int64)
@ Accessors ~/.julia/packages/Accessors/C574d/src/optics.jl:223
[2] map
@ ./tuple.jl:357 [inlined]
[3] modify
@ ~/.julia/packages/AccessorsExtra/GMk8B/src/modifymany.jl:1 [inlined]
[4] delete(obj::Tuple{Int64, Int64, Int64}, optic::ComposedFunction{Elements, Elements})
@ Accessors ~/.julia/packages/Accessors/C574d/src/optics.jl:222
[5] (::Accessors.var"#5#6"{ComposedFunction{ComposedFunction{Elements, Elements}, IndexLens{Tuple{String}}}})(inner_obj::Tuple{Int64, Int64, Int64})
@ Accessors ~/.julia/packages/Accessors/C574d/src/optics.jl:223
[6] _modify
@ ~/.julia/packages/Accessors/C574d/src/optics.jl:218 [inlined]
[7] modify
@ ~/.julia/packages/Accessors/C574d/src/optics.jl:198 [inlined]
[8] delete(obj::Dict{String, Tuple{Int64, Int64, Int64}}, optic::ComposedFunction{ComposedFunction{Elements, Elements}, IndexLens{Tuple{String}}})
@ Accessors ~/.julia/packages/Accessors/C574d/src/optics.jl:222
[9] top-level scope
@ REPL[12]:1
Is this supposed to work? Thanks! :)
Indeed, delete(x, @optic _["a"][∗]) could remove all elements of x["a"] so that x["a"] exists but is an empty collection. And delete(x, @optic _["a"][∗][∗]) would keep all x["a"][1], x["a"][2], ... leaving each of them empty.
I don't see any issues with following this semantic, I guess it just never came up and you have quite a rare usecase :)
Feel free to make an implementation PR! Defining delete(::Elements) methods for tuples and vectors should be enough.