0 | module Control.Monad.Bayes.Free
2 | import Control.Monad.Identity
3 | import Control.Monad.Trans
4 | import Control.Monad.State
5 | import Control.Monad.Writer
7 | import Control.Monad.Bayes.Interface
8 | import Control.Monad.Free
9 | import public Control.Monad.Trans.Free.Church
13 | data SamF a = Random (Double -> a)
17 | map f (Random k) = Random (f . k)
22 | FreeSampler : (m : Type -> Type) -> (a : Type) -> Type
23 | FreeSampler = FT SamF
26 | (Monad m, MonadFree SamF (FreeSampler m)) => MonadSample (FreeSampler m) where
27 | random = liftF $
Random id
31 | hoist : (Monad m, Monad n) => (forall x. m x -> n x) -> FreeSampler m a -> FreeSampler n a
32 | hoist f m = hoistFT f m
36 | interpret : MonadSample m => FreeSampler m a -> m a
37 | interpret c = iterT (\(Random k) => random >>= k) c
41 | withRandomness : Monad m => List Double -> FreeSampler m a -> m a
42 | withRandomness randomness = evalStateT randomness . iterTM f
43 | where f : MonadState (List Double) n => SamF (n b) -> n b
45 | xs <- the (n (List Double)) get
47 | [] => assert_total $
idris_crash ("withRandomness: randomness too short!")
48 | y :: ys => put ys >> k y
50 | MonadTrans (\m => StateT (List Double) (WriterT (List Double) m)) where
57 | withPartialRandomness : MonadSample m => List Double -> FreeSampler m a -> m (a, List Double)
58 | withPartialRandomness randomness k =
60 | evalStateT randomness $
61 | iterTM {t = \m => StateT (List Double) (WriterT (List Double) m) } f k
62 | where f : (MonadSample n, MonadWriter (List Double) n, MonadState (List Double) n) => SamF (n a) -> n a
64 | xs <- the (n (List Double)) get
67 | y :: ys => put ys >> pure y
73 | runWith : MonadSample m => List Double -> FreeSampler Identity a -> m (a, List Double)
74 | runWith randomness = withPartialRandomness randomness . hoist {n=m} (pure . runIdentity)