monad-bayes-1.2.0: src/Control/Monad/Bayes/Density/State.hs
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
-- |
-- Slower than Control.Monad.Bayes.Density.Free, so not used by default,
-- but more elementary to understand. Just uses standard
-- monad transformer techniques.
module Control.Monad.Bayes.Density.State where
import Control.Monad.Bayes.Class (MonadDistribution (random))
import Control.Monad.State (MonadState (get, put), StateT, evalStateT)
import Control.Monad.Writer
newtype DensityT m a = DensityT {getDensityT :: WriterT [Double] (StateT [Double] m) a} deriving newtype (Functor, Applicative, Monad)
instance MonadTrans DensityT where
lift = DensityT . lift . lift
instance (Monad m) => MonadState [Double] (DensityT m) where
get = DensityT $ lift $ get
put = DensityT . lift . put
instance (Monad m) => MonadWriter [Double] (DensityT m) where
tell = DensityT . tell
listen = DensityT . listen . getDensityT
pass = DensityT . pass . getDensityT
instance (MonadDistribution m) => MonadDistribution (DensityT m) where
random = do
trace <- get
x <- case trace of
[] -> random
r : xs -> put xs >> pure r
tell [x]
pure x
runDensityT :: (Monad m) => DensityT m b -> [Double] -> m (b, [Double])
runDensityT (DensityT m) = evalStateT (runWriterT m)