diff --git a/Project.toml b/Project.toml index d2db3d5a..62a301d5 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "InitialValues" uuid = "22cec73e-a1b8-11e9-2c92-598750a2cf9c" authors = ["Takafumi Arakaki "] -version = "0.1.0" +version = "0.2.0-DEV" [compat] julia = "1.0" diff --git a/src/InitialValues.jl b/src/InitialValues.jl index ae8168a3..311a4d69 100644 --- a/src/InitialValues.jl +++ b/src/InitialValues.jl @@ -123,6 +123,13 @@ def_impl(op, x, y) = InitialValues.hasinitialvalue(::Type{typeof($op)}) = true end +monoid_impl(op, x) = + quote + $op(::$(itypeof_impl(op)), $x::$(itypeof_impl(op))) = $x + $op($x, ::$(itypeof_impl(op))) = $x + $(def_impl(op, x, x)) + end + """ InitialValues.@def op [y = :x] @@ -149,34 +156,49 @@ macro def(op, y = :x) def_impl(esc(op), esc(:x), esc(y)) end -disambiguate_impl(op, right, x, y) = +""" + InitialValues.@monoid op + +Define a generic identity for a binary operator `op`. +`InitialValues.@monoid op` is expanded to + +```julia +$(prettyexpr(monoid_impl(:op, :x))) +``` +""" +macro monoid(op) + monoid_impl(esc(op), esc(:x)) +end + +disambiguate_impl(op, other, x) = quote - $op(::$(itypeof_impl(op)), $x::$right) = $y + $op(::$(itypeof_impl(op)), $x::$other) = $x + $op($x::$other, ::$(itypeof_impl(op))) = $x end """ - InitialValues.@disambiguate op RightType [y = :x] + InitialValues.@disambiguate op OtherType -Disambiguate the method introduced by [`@def`](@ref). +Disambiguate the method introduced by [`@monoid`](@ref). It is expanded to ```julia -$(prettyexpr(disambiguate_impl(:op, :RightType, :x, :x))) +$(prettyexpr(disambiguate_impl(:op, :OtherType, :x))) ``` """ -macro disambiguate(op, right, y = :x) - disambiguate_impl(esc(op), esc(right), esc(:x), esc(y)) +macro disambiguate(op, other) + disambiguate_impl(esc(op), esc(other), esc(:x)) end -@def Base.:* -@def Base.:+ -@def Base.:& -@def Base.:| -@def Base.min -@def Base.max -@def Base.add_sum -@def Base.mul_prod +@monoid Base.:* +@monoid Base.:+ +@monoid Base.:& +@monoid Base.:| +@monoid Base.min +@monoid Base.max +@monoid Base.add_sum +@monoid Base.mul_prod @disambiguate Base.min Missing @disambiguate Base.max Missing diff --git a/test/test_def.jl b/test/test_def.jl index 92d067e3..3595cf9d 100644 --- a/test/test_def.jl +++ b/test/test_def.jl @@ -8,7 +8,7 @@ module CleanNameSpace add(x, y) = x + y got(x) = string("Got: ", repr(x)) @def add got(x) - @disambiguate add Missing got(x) + @disambiguate add Missing end @testset "CleanNameSpace" begin @@ -17,7 +17,7 @@ end @test hasinitialvalue(add) @test isknown(Init(add)) @test add(Init(add), :x) == "Got: :x" - @test add(Init(add), missing) == "Got: missing" + @test add(Init(add), missing) === missing end module NonFunction @@ -26,7 +26,7 @@ module NonFunction const add = Add() add(x, y) = x + y @def add - @disambiguate add Missing "Got: $x" + @disambiguate add Missing end @testset "NonFunction" begin @@ -35,7 +35,7 @@ end @test hasinitialvalue(add) @test isknown(Init(add)) @test add(Init(add), :x) == :x - @test add(Init(add), missing) == "Got: missing" + @test add(Init(add), missing) === missing end end # module diff --git a/test/test_prettyexpr.jl b/test/test_prettyexpr.jl index 1da81dbf..c1493028 100644 --- a/test/test_prettyexpr.jl +++ b/test/test_prettyexpr.jl @@ -32,7 +32,7 @@ eq(x, y) = normalize(x) == normalize(y) ), ( label = "disambiguate_impl", - ex = disambiguate_impl(:op, :RightType, :x, :x), + ex = disambiguate_impl(:op, :RightType, :x), ), ] code = prettyexpr(ex)