Skip to content

Commit 987b6fa

Browse files
authored
allow non-type as first argument of make(x...) (#11)
Till now, `make(x)` was defined to create an explicit distribution wrapping a possibly implicit one (`x`). Beside this case, the first argument of `make(x1, xs...)` had to be a type (typically a supertype of the `gentype` of the resulting "make value"). But there is no reason to prevent allowing a non-type object as the first argument; in this case though, this non-type object `x1` has to be passed as an argument to `Make` (i.e. the resulting `Make` object contains `x1` as its first element), because keeping only its type would be lossy.
1 parent 2bb283f commit 987b6fa

3 files changed

Lines changed: 37 additions & 2 deletions

File tree

src/distributions.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ maketype(::Type{T}, x...) where {T} = T
3939

4040
make(::Type{T}, x...) where {T} = Make{maketype(T, x...)}(x...)
4141

42+
# make(x) is defined in sampling.jl, and is a special case wrapping already valid
43+
# distributions (explicit or implicit)
44+
make(x1, x2, xs...) = Make{maketype(x1, x2, xs...)}(x1, x2, xs...)
45+
4246
find_deduced_type(::Type{T}, ::X, ) where {T,X} = deduce_type(T, gentype(X))
4347
find_deduced_type(::Type{T}, ::Type{X}) where {T,X} = deduce_type(T, X)
4448

src/sampling.jl

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,21 @@ sampler(rng::AbstractRNG, X, n::Repetition=Val(Inf)) = sampler(typeof(rng), X, n
1515

1616
make() = make(Float64)
1717

18-
### type
18+
### type: handles e.g. rand(make(Int))
19+
20+
# rand(rng, ::SamplerType{Make0{X}}) should not be overloaded, as make(T)
21+
# has this special pass-thru Sampler defined below
1922

2023
Sampler(RNG::Type{<:AbstractRNG}, ::Make0{X}, n::Repetition) where {X} =
2124
Sampler(RNG, X, n)
2225

23-
### object
26+
### object: handles e.g. rand(make(1:3))
27+
28+
# make(x) where x isn't a type should create a distribution d such that rand(x) is
29+
# equivalent to rand(d); so we need to overload make(x) to give a different type
30+
# than Make1{gentype(x)}, as we can't simply define a generic pass-thru Sampler for
31+
# that Make1 type (because users expect the default to be a SamplerTrivial{<:Make1{...}},
32+
# and might want to define only a rand method on this SamplerTrivial)
2433

2534
# like Make1
2635
struct MakeWrap{T,X} <: Distribution{T}

test/runtests.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,28 @@ end
579579
@test nt isa NTuple{4,Complex{Int64}}
580580
end
581581

582+
## make(x1, xs...)
583+
584+
struct MyType
585+
x
586+
end
587+
588+
RandomExtensions.maketype(x::MyType, y) = eltype(x.x:y)
589+
590+
Base.rand(rng::AbstractRNG,
591+
x::Random.SamplerTrivial{<:RandomExtensions.Make2{<:Integer, MyType}}) =
592+
rand(rng, x[][1].x:x[][2])
593+
594+
@testset "rand(make(CustomType(), ...))" begin
595+
m = MyType(3)
596+
@test rand(make(m, 3)) == 3
597+
@test rand(make(m, big(5))) isa BigInt
598+
@test rand(make(m, big(5))) 3:5
599+
a = rand(make(m, big(6)), 5)
600+
@test a isa Vector{BigInt}
601+
@test length(a) == 5
602+
@test all((3:6), a)
603+
end
582604

583605
## @rand
584606

0 commit comments

Comments
 (0)