From 0effa2a553b67545a93e622768fdf3dfe848af2c Mon Sep 17 00:00:00 2001 From: Alexander Plavin Date: Sat, 20 Jul 2024 12:09:34 -0400 Subject: [PATCH 1/2] more function optics --- src/functionlenses.jl | 3 +++ test/test_functionlenses.jl | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/functionlenses.jl b/src/functionlenses.jl index 2d3b0d58..73744286 100644 --- a/src/functionlenses.jl +++ b/src/functionlenses.jl @@ -138,12 +138,14 @@ function set(x, ::typeof(abs), y) s = sign(x) iszero(s) ? y * one(x) : y * s end +set(x, ::typeof(abs2), y) = set(x, abs, √y) set(x, ::typeof(mod2pi), y) = set(x, @optic(mod(_, 2π)), y) set(x, f::Base.Fix2{typeof(fld)}, y) = set(x, @optic(first(fldmod(_, f.x))), y) set(x, f::Base.Fix2{typeof(mod)}, y) = set(x, @optic(last(fldmod(_, f.x))), y) set(x, f::Base.Fix2{typeof(div)}, y) = set(x, @optic(first(divrem(_, f.x))), y) set(x, f::Base.Fix2{typeof(rem)}, y) = set(x, @optic(last(divrem(_, f.x))), y) +set(x, f::Base.Fix2{typeof(mod),<:AbstractUnitRange}, y) = @set mod($x - first(f.x), length(f.x)) + first(f.x) = y set(x::AbstractString, f::Base.Fix1{typeof(parse), Type{T}}, y::T) where {T} = string(y) @@ -171,6 +173,7 @@ delete(s::AbstractString, o::typeof(last)) = chop(s; head=0, tail=1) delete(s::AbstractString, o::Base.Fix2{typeof(first)}) = chop(s; head=o.x, tail=0) delete(s::AbstractString, o::Base.Fix2{typeof(last)}) = chop(s; head=0, tail=o.x) +set(s::AbstractString, o::typeof(chomp), v) = endswith(s, '\n') ? v * '\n' : v if VERSION >= v"1.8" set(s::AbstractString, o::Base.Fix2{typeof(chopsuffix), <:AbstractString}, v) = endswith(s, o.x) ? v * o.x : v diff --git a/test/test_functionlenses.jl b/test/test_functionlenses.jl index c9c9947c..443e238e 100644 --- a/test/test_functionlenses.jl +++ b/test/test_functionlenses.jl @@ -257,7 +257,7 @@ end # invertible lenses below: no need for extensive testing, simply forwarded to InverseFunctions inv, +, exp, sqrt, @optic(2 + _), @optic(_ * 3), @optic(log(2, _)), # non-invertible lenses, indirectly forwarded to InverseFunctions - @optic(mod(_, 21)), @optic(fld(_, 3)), @optic(rem(_, 21)), @optic(div(_, 3)), + @optic(mod(_, 21)), @optic(fld(_, 3)), @optic(rem(_, 21)), @optic(div(_, 3)), @optic(mod(_, 1:22)), ] x = 5 test_getset_laws(o, x, 10, 20; cmp=isapprox) @@ -272,6 +272,7 @@ end @test set(0+0im, abs, 10) == 10 @test set(0+1e-100im, abs, 10) == 10im @test_throws DomainError @set(abs(x) = -10) + test_getset_laws(abs2, 1+2im, 3, 4, cmp=(≈)) # composition o = @optic 1/(1 + exp(-_)) @@ -362,6 +363,9 @@ end test_getset_laws(@optic(lstrip(==(' '), _)), " abc ", "def", "") test_getset_laws(@optic(rstrip(==(' '), _)), " abc ", "def", "") test_getset_laws(@optic(strip(==(' '), _)), " abc ", "def", "") + test_getset_laws(chomp, "abc", "def", "") + test_getset_laws(chomp, "abc\n", "def", "") + test_getset_laws(chomp, "abc\n\n", "def\n", "") if VERSION >= v"1.8" test_getset_laws(@optic(chopprefix(_, "def")), "def abc", "xyz", "") From bb39276cd4cbb905d4b2cb247558d646405dab33 Mon Sep 17 00:00:00 2001 From: Alexander Plavin Date: Tue, 30 Jul 2024 23:32:39 -0400 Subject: [PATCH 2/2] more mod tests --- test/test_extensions.jl | 4 ++++ test/test_functionlenses.jl | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/test/test_extensions.jl b/test/test_extensions.jl index a351fa6f..0c23cb3f 100644 --- a/test/test_extensions.jl +++ b/test/test_extensions.jl @@ -66,6 +66,10 @@ VERSION >= v"1.9-" && @testset "IntervalSets" begin @test 2 === @set 2 |> mod(_, 20..23) = 20 @test 33 === @set 32 |> mod(_, 20..23) = 21 test_getset_laws(@optic(mod(_, 5..8)), 20, 6, 5) + + @test_throws Exception mod(3, 1..0) + @test_throws Exception @set mod($3, 1..0) = 1 + @test_throws Exception @set mod($3, 1..5) = 10 end @testset "StaticArrays" begin diff --git a/test/test_functionlenses.jl b/test/test_functionlenses.jl index 443e238e..9ebdfc26 100644 --- a/test/test_functionlenses.jl +++ b/test/test_functionlenses.jl @@ -257,12 +257,25 @@ end # invertible lenses below: no need for extensive testing, simply forwarded to InverseFunctions inv, +, exp, sqrt, @optic(2 + _), @optic(_ * 3), @optic(log(2, _)), # non-invertible lenses, indirectly forwarded to InverseFunctions - @optic(mod(_, 21)), @optic(fld(_, 3)), @optic(rem(_, 21)), @optic(div(_, 3)), @optic(mod(_, 1:22)), + @optic(mod(_, 21)), @optic(fld(_, 3)), @optic(rem(_, 21)), @optic(div(_, 3)), ] x = 5 test_getset_laws(o, x, 10, 20; cmp=isapprox) @inferred set(x, o, 10) end + + @testset for (rng, x, y) in [ + (0:3, 2, 1), + (0:3, 32, 1), + (20:23, 2, 20), + (20:23, 32, 21), + (5:8, 20, 6), + ] + test_getset_laws((@o mod(_, rng)), x, y, y+1) + end + @test_throws Exception mod(3, 1:0) + @test_throws Exception @set mod($3, 1:0) = 1 + @test_throws Exception @set mod($3, 1:5) = 10 x = 3 + 4im @test @set(abs(-2u"m") = 1u"m") === -1u"m"