When I am developing packages, I often come across the following problem.
struct Step{T} end
func(::Step{1}, x) = do something...
func(::Step{2}, x) = do some different things...
I am not sure should I use singleton types Type{Step{1}}
and Type{Step{2}}
, instead of singletons Step{1}
and Step{2}
to dispatch behaviors?
func(::Type{Step{1}}, x) = do something...
func(::Type{Step{2}}, x) = do some different things...
Julia’s doc says instances should be used, is it a general rule or just for Val
type? Because I have seen both of them be used in different packages:
- Using instances (like
Bisection()
)
using Roots
# struct Bisection <: AbstractBisection end # either solvable or A42
f(x) = exp(x) - x^4
# a bisection method has the bracket specified with a tuple or vector
julia> find_zero(f, (8,9), Bisection())
8.613169456441398
- Using singleton types (like
Newton
):
using IntervalRootFinding
roots(log, -2..2, Newton)
- Which one is a better practice?
- Can those types (
Step
,Bisection
,Newton
) be called “traits”? - If we use singleton types (
Type{Step}
), should I just let the typeStep
be an abstract type, instead of a concrete type?