Functional Python Programming

(Wang) #1

The PyMonad Library


We rolled the dice once to determine if we have a first-roll win, loss, or point.
We return an appropriate monad value that includes the outcome, a point value,
and the roll of the dice. The point values for an immediate win and immediate
loss aren't really meaningful. We could sensibly return a 0 here, since no point
was really established.


The point_roll() function looks like this:


@curry


def point_roll(dice, status):


prev, point, so_far = status


if prev != "point":


return Just(status)


d = dice()


if sum(d) == 7:


return Just(("craps", point, so_far+[d]))


elif sum(d) == point:


return Just(("win", point, so_far+[d]))


else:


return Just(("point", point, so_far+[d])) >> point_roll(dice)


We decomposed the status monad into the three individual values of the tuple.
We could have used small lambda objects to extract the first, second, and third
values. We could also have used the operator.itemgetter() function to extract
the tuples' items. Instead, we used multiple assignment.


If a point was not established, the previous state will be "win" or "lose". The game
was resolved in a single throw, and this function simply returns the status monad.


If a point was established, the dice are rolled and rules applied to the new roll.
If roll is 7, the game is a loser and a final monad is returned. If the roll is the point,
the game is a winner and the appropriate monad is returned. Otherwise, a slightly
revised monad is passed to the point_roll() function. The revised status monad
includes this roll in the history of rolls.


A typical output looks like this:





craps()





('craps', 5, [(2, 3), (1, 3), (1, 5), (1, 6)])

Free download pdf