Skip to content

Instantly share code, notes, and snippets.

@JeffreySarnoff
Last active November 29, 2023 00:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JeffreySarnoff/03857abc132c1ba0ebd883d040e410e0 to your computer and use it in GitHub Desktop.
Save JeffreySarnoff/03857abc132c1ba0ebd883d040e410e0 to your computer and use it in GitHub Desktop.
provide a dispatchable singleton Zero
struct ZERO end
const Zero = ZERO()
# to display Zero as Zero
const ShowZero = :Zero
# to display Zero as 0
# const ShowZero = 0
Base.show(io::IO, x::ZERO) = print(io, ShowZero)
Base.zero(::ZERO) = 0
Base.iszero(x::ZERO) = true
Base.convert(::Type{T}, x::ZERO) where {T} = zero(T)
Base.promote_rule(::Type{T}, ::Type{ZERO}) where {T} = T
Base.convert(::Type{ZERO}, x::T) where {T<:Real} =
iszero(x) ? Zero : throw(DomainError("0 != $(x)"))
for Op in (:(+), :(-), :(*), :(/))
@eval begin
Base.$Op(x::ZERO, y::ZERO) = 0
Base.$Op(x::T, y::ZERO) where {T<:Real} = $Op(x, 0)
Base.$Op(x::ZERO, y::T) where {T<:Real} = $Op(0, y)
end
end
# dispatch
dispatch(x) = false
dispatch(x::ZERO) = true
dispatch(Zero), dispatch(0), dispatch(5)
# (true, false, false)
dispatch0(x) = iszero(x) ? true : false
dispatch0(x::ZERO) = true
dispatch0(Zero), dispatch0(0), dispatch0(5)
# (true, true, false)
# test
iszero(Zero)
# true
# arithmetic
Zero + Zero, Zero + 1, 1 + Zero
# (0, 1, 1)
Zero * Zero, Zero * 2, 2 * Zero
# (0, 0, 0)
# display
Zero
# Zero # 0 if you chose that for ShowZero
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment