Closed
Description
Currently we have:
pub trait RngCore { ... }
pub trait Rng: RngCore { ... }
impl<'a, R: RngCore + ?Sized> RngCore for &'a mut R { ... }
pub trait Distribution<T> {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> T;
}
impl Distribution<f64> for Exp {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
let n: f64 = rng.sample(Exp1);
n * self.lambda_inverse
}
}
In my master experimental branch the Distribution
trait is slightly different:
pub trait Distribution<T> {
fn sample<R: RngCore + ?Sized>(&self, rng: &mut R) -> T;
}
impl Distribution<f64> for Exp {
fn sample<R: RngCore + ?Sized>(&self, rng: &mut R) -> f64 {
let n: f64 = rng.sample(Exp1);
n * self.lambda_inverse
}
}
Are they equivalent? Almost, but:
What doesThe constraint is relaxed.R: Rng + ?Sized
mean whenRng: Sized
and why does this work?Why doesUniform.sample(&mut r)
wherer: &mut RngCore
work in the latter case? This does work in both cases which is the main thing.Rng
is implemented for everyRngCore
so effectivelyr: &mut Rng
.- It is necessary to import both
Rng
andRngCore
to implementDistribution
in the latter It is often necessary to writemut rng
when implementingDistribution
in the latter
Are there any subtleties I'm missing? The former is slightly more convenient, but I don't understand it as well as the latter. @burdges do you understand this better?