This question is part theory / part implementation. Background assumption: I'm using the monad-bayes library to represent probability distributions as monads. A distribution p(a|b) can be represented as a function MonadDist m => b -> m a
.
Suppose I have a conditional probability distribution s :: MonadDist m => [Char] -> m Char
. I want to get a new probability distribution sUnrolled :: [Char] -> m [Char]
, defined mathematically (I think) as:
sUnrolled(chars|st) =
| len(chars)==1 -> s st
| otherwise -> s(chars[-1]|st++chars[:-1]) * sUnrolled(chars[:-1]|st)
Intuitively it's the distribution you get by taking st :: [Char]
, sampling a new char c
from s st
, feeding st++[c]
back into s
, and so on. I believe iterateM s
is more or less what I want. To make it a distribution we could actually look at, let's say that if we hit a certain character, we stop. Then iterateMaybeM
works.
Theory Question: For various reasons, it would be really useful if I could express this distribution in more general terms, for instance in a way that generalized to the stochastic construction of a tree given a stochastic coalgebra. It looks like I have some sort of anamorphism here (I realize that the mathematical definition looks like a catamorphism, but in code I want to build up strings, not deconstruct them into probabilities) but I can't quite work out the details, not least because of the presence of the probability monad.
Practical Question: it would also be useful to implement this in Haskell in a way that used the recursion schemes library, for instance.