From bcd49ec34f3de1e723337e828a11c33c17f5e0f5 Mon Sep 17 00:00:00 2001 From: Pevnak Date: Sat, 28 Nov 2020 21:06:43 +0100 Subject: [PATCH 1/3] added an initial version of normalise, propname, and decompose --- src/sugar.jl | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/sugar.jl b/src/sugar.jl index ca3e742d..63a71561 100644 --- a/src/sugar.jl +++ b/src/sugar.jl @@ -275,3 +275,61 @@ function show_composition_order(io::IO, lens::ComposedOptic) print(io, ")") end + +""" + decompose(optic) + +decomposes the `ComposedOptic` into tuple of simple properties (Lenses) +while preserving the order + +```julia +julia> decompose(@optic _.a.b.c.d) +((@optic _.d), (@optic _.c), (@optic _.b), (@optic _.a)) + +julia> decompose((@optic _.c.d) ∘ (@optic _.a.b)) +((@optic _.d), (@optic _.c), (@optic _.b), (@optic _.a)) +""" +decompose(optic) = (optic,) +decompose(optic::ComposedOptic) = (decompose(optic.outer)..., decompose(optic.inner)...) + +""" + propname(::PropertyLens{name}) + +returns the name of the propery lens +```julia +julia> propname(@optic _.a) +:a +``` + +Using `propname` with `decompose`, list all keys of can be listed as +```julia +julia> map(propname, decompose((@optic _.c.d) ∘ (@optic _.a.b)) +(:d, :c, :b, :a) +``` +""" +propname(::PropertyLens{name}) where {name} = name + + +""" + normalise(optic) + +transforms the optic such that the `inner` lens contains always a the `PropertyLens` + +```julia +julia> optic = (@optic _.a) ∘ (@optic _.b.c) +(@optic _.a) ∘ (@optic _.c) ∘ (@optic _.b) + +julia> optic.inner +(@optic _.c) ∘ (@optic _.b) + +julia> optic.outer +(@optic _.a) + +julia> normalise(optic).inner +(@optic _.b) + +julia> normalise(optic).outer +(@optic _.a) ∘ (@optic _.c) +""" +normalise(optic) = optic +normalise(optic::ComposedOptic) = foldl(∘, decompose(optic)) From 4594d7cd6dd5bf922983649a7f7995aa0f29724a Mon Sep 17 00:00:00 2001 From: Pevnak Date: Sat, 28 Nov 2020 21:22:33 +0100 Subject: [PATCH 2/3] added tests --- src/sugar.jl | 10 +++++----- test/test_optics.jl | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/sugar.jl b/src/sugar.jl index 63a71561..caac9346 100644 --- a/src/sugar.jl +++ b/src/sugar.jl @@ -316,20 +316,20 @@ propname(::PropertyLens{name}) where {name} = name transforms the optic such that the `inner` lens contains always a the `PropertyLens` ```julia -julia> optic = (@optic _.a) ∘ (@optic _.b.c) -(@optic _.a) ∘ (@optic _.c) ∘ (@optic _.b) +julia> optic = (@optic _.c) ∘ (@optic _.a.b) +(@optic _.c) ∘ (@optic _.b) ∘ (@optic _.a) julia> optic.inner -(@optic _.c) ∘ (@optic _.b) +(@optic _.b) ∘ (@optic _.a) julia> optic.outer (@optic _.a) julia> normalise(optic).inner -(@optic _.b) +(@optic _.a) julia> normalise(optic).outer -(@optic _.a) ∘ (@optic _.c) +(@optic _.c) ∘ (@optic _.b) """ normalise(optic) = optic normalise(optic::ComposedOptic) = foldl(∘, decompose(optic)) diff --git a/test/test_optics.jl b/test/test_optics.jl index adf774ea..db79a942 100644 --- a/test/test_optics.jl +++ b/test/test_optics.jl @@ -45,4 +45,18 @@ end @inferred modify(x -> 0, arr, @optic _ |> Elements() |> If(iseven)) end +@testset "Decomposition" begin + @test Accessors.decompose(@optic _.a.b.c) == ((@optic _.c), (@optic _.b), (@optic _.a)) +end + +@testset "Propname" begin + @test Accessors.propname(@optic _.a) == :a +end + +@testset "Normalisation" begin + @test Accessors.normalise((@optic _.c) ∘ (@optic _.a.b)).inner == @optic _.a + @test Accessors.normalise((@optic _.c) ∘ (@optic _.a.b)).outer.inner == @optic _.b + @test Accessors.normalise((@optic _.c) ∘ (@optic _.a.b)).outer.outer == @optic _.c +end + end#module From 60fc955f74f805e0024782a580d06c2b56306188 Mon Sep 17 00:00:00 2001 From: Pevnak Date: Sat, 28 Nov 2020 21:24:43 +0100 Subject: [PATCH 3/3] added tests --- src/sugar.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sugar.jl b/src/sugar.jl index caac9346..6709d8f2 100644 --- a/src/sugar.jl +++ b/src/sugar.jl @@ -288,6 +288,7 @@ julia> decompose(@optic _.a.b.c.d) julia> decompose((@optic _.c.d) ∘ (@optic _.a.b)) ((@optic _.d), (@optic _.c), (@optic _.b), (@optic _.a)) +``` """ decompose(optic) = (optic,) decompose(optic::ComposedOptic) = (decompose(optic.outer)..., decompose(optic.inner)...) @@ -330,6 +331,7 @@ julia> normalise(optic).inner julia> normalise(optic).outer (@optic _.c) ∘ (@optic _.b) +``` """ normalise(optic) = optic normalise(optic::ComposedOptic) = foldl(∘, decompose(optic))