diff --git a/README.md b/README.md index 179b796..b58ff48 100644 --- a/README.md +++ b/README.md @@ -221,13 +221,17 @@ Note that it's easy to get the result of the second interpretation via either `r `rand(String, (3,))` or `rand(String, Vector, 3)`. How to extend: the `make` function is meant to be extensible, and there are some helper functions -which make it easy, but the internals are not fully settled. By default, `make(T, args...)` will +which make it easy, but this is still experimental. By default, `make(T, args...)` will create a `Make{maketype(T, args...)}` object, say `m`, which contain `args...` as fields. For type stable code, the `rand` machinery likes to know the exact type of the object which will be generated by `rand(m)`, and `maketype(T, args...)` is supposed to return that type. For example, `maketype(Pair, 1:3, UInt) == Pair{Int,UInt}`. Then just define `rand` for `m` like documented in the `Random` module, e.g. `rand(rng::AbstractRNG, sp::SamplerTrivial{<:Make{P}}) where {P<:Pair} = P(rand(sp[].x), rand(sp[].y))`. +For convenience, `maketype(T, ...)` defaults to `T`, which means that for simple cases, only the +`rand` function has to be defined. But in cases like for `Pair` above, if `maketype` is not +defined, the generated type will be assumed to be `Pair`, which is not a concrete type +(and hence suboptimal). This package started out of frustration with the limitations of the `Random` module. Besides generating simple scalars and arrays, very little is supported out of the box. For example, diff --git a/src/distributions.jl b/src/distributions.jl index 508b8d7..4b25213 100644 --- a/src/distributions.jl +++ b/src/distributions.jl @@ -15,6 +15,9 @@ Make( ::Type{T}) where {T} = Make0{T}() Make0(::Type{T}) where {T} = Make0{T}() make(::Type{T}) where {T} = Make0{maketype(T)}() +# default +maketype(::Type{T}) where {T} = T + struct Make1{T,X} <: Make{T} x::X end @@ -29,6 +32,9 @@ Make1{T}(::Type{X}) where {T,X} = Make1{T,Type{X}}(X) make(::Type{T}, x::X) where {T,X} = Make{maketype(T,x)}(x) make(::Type{T}, ::Type{X}) where {T,X} = Make{maketype(T,X)}(X) +# default +maketype(::Type{T}, x) where {T} = T + find_deduced_type(::Type{T}, ::X, ) where {T,X} = deduce_type(T, gentype(X)) find_deduced_type(::Type{T}, ::Type{X}) where {T,X} = deduce_type(T, X) @@ -53,6 +59,9 @@ make(::Type{T}, ::Type{X}, y::Y) where {T,X,Y} = Make{maketype(T,X,y)}(X, y make(::Type{T}, x::X, ::Type{Y}) where {T,X,Y} = Make{maketype(T,x,Y)}(x, Y) make(::Type{T}, ::Type{X}, ::Type{Y}) where {T,X,Y} = Make{maketype(T,X,Y)}(X, Y) +# default +maketype(::Type{T}, x, y) where {T} = T + find_deduced_type(::Type{T}, ::X, ::Y) where {T,X,Y} = deduce_type(T, gentype(X), gentype(Y)) find_deduced_type(::Type{T}, ::Type{X}, ::Y) where {T,X,Y} = deduce_type(T, X, gentype(Y)) find_deduced_type(::Type{T}, ::X, ::Type{Y}) where {T,X,Y} = deduce_type(T, gentype(X), Y) @@ -93,6 +102,8 @@ make(::Type{T}, ::Type{X}, y::Y, ::Type{Z}) where {T,X,Y,Z} = Make3{maketyp make(::Type{T}, x::X, ::Type{Y}, ::Type{Z}) where {T,X,Y,Z} = Make3{maketype(T, x, Y, Z)}(x, Y, Z) make(::Type{T}, ::Type{X}, ::Type{Y}, ::Type{Z}) where {T,X,Y,Z} = Make3{maketype(T, X, Y, Z)}(X, Y, Z) +# default +maketype(::Type{T}, x, y, z) where {T} = T # deduce_type diff --git a/src/sampling.jl b/src/sampling.jl index 7b1f39e..d3ba577 100644 --- a/src/sampling.jl +++ b/src/sampling.jl @@ -17,8 +17,6 @@ make() = make(Float64) ### type -maketype(::Type{X}) where{X} = X - Sampler(RNG::Type{<:AbstractRNG}, ::Make0{X}, n::Repetition) where {X} = Sampler(RNG, X, n) diff --git a/test/runtests.jl b/test/runtests.jl index 0e32f6b..351742e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -491,10 +491,10 @@ end @test s isa Arr{dim} @test length(s) == 6 end - @test_throws MethodError make(Matrix, 2) - @test_throws MethodError make(Vector, 2, 3) - @test_throws MethodError make(BitMatrix, 2) - @test_throws MethodError make(BitVector, 2, 3) + @test_throws MethodError rand(make(Matrix, 2)) + @test_throws MethodError rand(make(Vector, 2, 3)) + @test_throws MethodError rand(make(BitMatrix, 2)) + @test_throws MethodError rand(make(BitVector, 2, 3)) @test rand(make(Array, spString, 9)) isa Array{String} @test rand(make(BitArray, Sampler(MersenneTwister, [0, 0, 0, 1]), 9)) isa BitArray