Skip to content

Commit 8a22d90

Browse files
authored
Random: introduce gentype, instead of punning on eltype (#27756)
In some cases it makes sense to define what type of value `rand(rng, x)` will produce, via the newly introduced `gentype(x)`, without having `eltype(x)` be meaningful.
1 parent ddc4908 commit 8a22d90

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

stdlib/Random/src/Random.jl

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,25 @@ export srand,
3434

3535
abstract type AbstractRNG end
3636

37+
"""
38+
Random.gentype(T)
39+
40+
Determine the type of the elements generated by calling `rand([rng], x)`,
41+
where `x::T`, and `x` is not a type.
42+
The definition `gentype(x) = gentype(typeof(x))` is provided for convenience,
43+
and `gentype(T)` defaults to `eltype(T)`.
44+
NOTE: `rand([rng], X)`, where `X` is a type, is always assumed to produce
45+
an object of type `X`.
46+
47+
# Examples
48+
```jldoctest
49+
julia> gentype(1:10)
50+
Int64
51+
```
52+
"""
53+
gentype(::Type{X}) where {X} = eltype(X)
54+
gentype(x) = gentype(typeof(x))
55+
3756

3857
### integers
3958

@@ -72,7 +91,7 @@ for UI = (:UInt10, :UInt10Raw, :UInt23, :UInt23Raw, :UInt52, :UInt52Raw,
7291
end
7392
end
7493

75-
Base.eltype(::Type{<:UniformBits{T}}) where {T} = T
94+
gentype(::Type{<:UniformBits{T}}) where {T} = T
7695

7796
### floats
7897

@@ -88,15 +107,15 @@ const CloseOpen12_64 = CloseOpen12{Float64}
88107
CloseOpen01(::Type{T}=Float64) where {T<:AbstractFloat} = CloseOpen01{T}()
89108
CloseOpen12(::Type{T}=Float64) where {T<:AbstractFloat} = CloseOpen12{T}()
90109

91-
Base.eltype(::Type{<:FloatInterval{T}}) where {T<:AbstractFloat} = T
110+
gentype(::Type{<:FloatInterval{T}}) where {T<:AbstractFloat} = T
92111

93112
const BitFloatType = Union{Type{Float16},Type{Float32},Type{Float64}}
94113

95114
### Sampler
96115

97116
abstract type Sampler{E} end
98117

99-
Base.eltype(::Type{<:Sampler{E}}) where {E} = E
118+
gentype(::Type{<:Sampler{E}}) where {E} = E
100119

101120
# temporarily for BaseBenchmarks
102121
RangeGenerator(x) = Sampler(GLOBAL_RNG, x)
@@ -133,7 +152,7 @@ struct SamplerTrivial{T,E} <: Sampler{E}
133152
self::T
134153
end
135154

136-
SamplerTrivial(x::T) where {T} = SamplerTrivial{T,eltype(T)}(x)
155+
SamplerTrivial(x::T) where {T} = SamplerTrivial{T,gentype(T)}(x)
137156

138157
Sampler(::AbstractRNG, x, ::Repetition) = SamplerTrivial(x)
139158

@@ -145,14 +164,14 @@ struct SamplerSimple{T,S,E} <: Sampler{E}
145164
data::S
146165
end
147166

148-
SamplerSimple(x::T, data::S) where {T,S} = SamplerSimple{T,S,eltype(T)}(x, data)
167+
SamplerSimple(x::T, data::S) where {T,S} = SamplerSimple{T,S,gentype(T)}(x, data)
149168

150169
Base.getindex(sp::SamplerSimple) = sp.self
151170

152171
# simple sampler carrying a (type) tag T and data
153172
struct SamplerTag{T,S,E} <: Sampler{E}
154173
data::S
155-
SamplerTag{T}(s::S) where {T,S} = new{T,S,eltype(T)}(s)
174+
SamplerTag{T}(s::S) where {T,S} = new{T,S,gentype(T)}(s)
156175
end
157176

158177

@@ -223,7 +242,7 @@ end
223242
rand(r::AbstractRNG, dims::Integer...) = rand(r, Float64, Dims(dims))
224243
rand( dims::Integer...) = rand(Float64, Dims(dims))
225244

226-
rand(r::AbstractRNG, X, dims::Dims) = rand!(r, Array{eltype(X)}(undef, dims), X)
245+
rand(r::AbstractRNG, X, dims::Dims) = rand!(r, Array{gentype(X)}(undef, dims), X)
227246
rand( X, dims::Dims) = rand(GLOBAL_RNG, X, dims)
228247

229248
rand(r::AbstractRNG, X, d::Integer, dims::Integer...) = rand(r, X, Dims((d, dims...)))
@@ -232,7 +251,7 @@ rand( X, d::Integer, dims::Integer...) = rand(X, Dims((d, dims...
232251
# rand(r, ()) would match both this method and rand(r, dims::Dims)
233252
# moreover, a call like rand(r, NotImplementedType()) would be an infinite loop
234253

235-
rand(r::AbstractRNG, ::Type{X}, dims::Dims) where {X} = rand!(r, Array{eltype(X)}(undef, dims), X)
254+
rand(r::AbstractRNG, ::Type{X}, dims::Dims) where {X} = rand!(r, Array{X}(undef, dims), X)
236255
rand( ::Type{X}, dims::Dims) where {X} = rand(GLOBAL_RNG, X, dims)
237256

238257
rand(r::AbstractRNG, ::Type{X}, d::Integer, dims::Integer...) where {X} = rand(r, X, Dims((d, dims...)))

stdlib/Random/test/runtests.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -681,8 +681,8 @@ end
681681
end
682682
end
683683

684-
@testset "eltype for UniformBits" begin
685-
@test eltype(Random.UInt52()) == UInt64
686-
@test eltype(Random.UInt52(UInt128)) == UInt128
687-
@test eltype(Random.UInt104()) == UInt128
684+
@testset "gentype for UniformBits" begin
685+
@test Random.gentype(Random.UInt52()) == UInt64
686+
@test Random.gentype(Random.UInt52(UInt128)) == UInt128
687+
@test Random.gentype(Random.UInt104()) == UInt128
688688
end

0 commit comments

Comments
 (0)