Skip to content

Distribution sample prototype and sized-ness of Rng #287

Closed
@dhardy

Description

@dhardy

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 does R: Rng + ?Sized mean when Rng: Sized and why does this work? The constraint is relaxed.
  • Why does Uniform.sample(&mut r) where r: &mut RngCore work in the latter case? This does work in both cases which is the main thing. Rng is implemented for every RngCore so effectively r: &mut Rng.
  • It is necessary to import both Rng and RngCore to implement Distribution in the latter
  • It is often necessary to write mut rng when implementing Distribution 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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    B-APIBreakage: APIE-questionParticipation: opinions wantedP-highPriority: high

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions