abstract type RejectionBasedSampler <: AbstractSampler end struct MetropolisHastings{P <: AbstractProposal} <: RejectionBasedSampler proposal :: P end function AbstractMCMC.step(rng::AbstractRNG, model::AbstractModel, sampler::MetropolisHastings; kwargs...) x = rand(rng, sampler.proposal) f_x = logdensity(model, x) return (true, x, f_x), (x, f_x) end function AbstractMCMC.step(rng::AbstractRNG, model::AbstractModel, sampler::MetropolisHastings, state; kwargs...) x, f_x = state y = propose(rng, sampler.proposal, x) f_y = logdensity(model, y) q = logpratio(sampler.proposal, x, y) A = min( f_y - f_x + q, 0) accept = log(rand(rng)) < A if accept return (true, y, f_y), (y, f_y) else return (false, x, f_x), (x, f_x) end end