As an example, consider rolling a die, and then rolling N dice (where N is the number you rolled on the first die). You want to know the total of that second roll. (This example is inspired by the rules of a game called "To Court the King").
So you want is, in effect
first = die(6) result = dice(first,6)
but this doesn't work, of course, because
first is a distribution, not a number.
I have been using the following function:
def mapdist(dist, fn): """Call fn on each value of a distribution, and merge the results. fn should take a single value as argument, and return a distribution.""" vps =  for v, p in dist.vps(): for v1, p1 in fn(v).vps(): vps.append((v1, p * p1)) return Lea.fromValFreqs(*vps)
I'm not entirely sure I like the name, but the idea seems sound. It seems to work on this example, at least, although a more complex example I'm working on:
dist = Lea.if_((hits == N) || (left == 0), sofar + hits, mapdist(left, lambda l: rest(Lea.binom(l, 1, 6), l, sofar + hits))
is failing with an error that
Lea.binom() needs a strictly positive integer (which means that this case wasn't filtered out by the first part of the
if_. I'm not sure if that's the fault of my implementation (and it should work) or if I'm musunderstanding how
Regardless of these details, I think the
mapdist function would be a useful addition to the library.