I have multiple functions with the same pattern:
foo(rng::AbstractRNG, x::ValueType) = ...
which are commonly applied to arrays as
foo.(rng::AbstractRNG, a::Array{ValueType})
which is supposed to be equivalent to, essentially
reshape([foo(rng, x) for x in a], size(a))
rng
here is a MersenneTwister
-type value, but I guess the question applies to any other kind of RNG. For just the code above, I get an error
MethodError: no method matching length(::MersenneTwister)
In order to make it work I have to wrap a MersenneTwister
in my own type and define length()
and iterate()
for it.
Is there some caveat Iām missing which is the reason these methods are not defined in Random
?
In fact, since I need this kind of ābroadcastabilityā for many other types, I have the following abstract type defined:
abstract type BroadcastableSingleton end
Base.length(::BroadcastableSingleton) = 1
Base.iterate(x::BroadcastableSingleton) = (x, nothing)
Base.iterate(x::BroadcastableSingleton, state) = nothing
This reduces boilerplate code, but wonāt be too clear if there are already some complicated abstract type hierarchies in place. I wonder if there is a better way to do it? (Canāt help but miss Haskellās data classes here)