Instructor: We start with an initial state that has a cards attribute defining an array of card objects. We also have a Left that keeps track of the number of moves the player has left, and finally, a moves counter, that increments every time the player makes a move.
Popping over to our answer model, we have a function, selectCard, that takes a string to a state, appStateOfUnit. selectCard selects a given card in our Cards array. To decrement the moves left, we defined this decLeft transition that takes a unit to a state, appStateOfUnit.
Last but not least, we have incMoves that also takes a unit to a state appStateOfUnit, which we use to increment the moves a player has taken. Because both these transitions always happen at the same time, we've combined incMoves and decLeft into this Kleisli composition called the applyMove that, you guessed it, takes a unit to a state appStateOfUnit.
We would like all of these transitions to occur when the player provides an answer. We create this answer transition that takes an ID for the answer. We define answer as a function that takes a string and returns us a brand-new state, appStateOfUnit.
To see how we get the ID into our state, let's first lift it into a state instance using state.of, giving it our ID. To keep leakage to a minimum, the only thing we'll export from this file is our answer transition, keeping the others safe from prying eyes.
To see what this is doing by lifting our ID with Of, let's move to the top of our index and we'll import our answer function from its location at dataModelAnswer. We'll take a quick peek at what resides in our resultant by replacing our state in this log function with a call to answer, providing it an ID of green-square, which gives us back a state instance, ready to be run.
AsOf lifts a value into the resultant. We pass our state to evalWidth, getting back the expected green-square, and a quick call to exec(with) shows that nothing has happened to our state. With our resultant populated, we chain in a call to selectCard, which passes it our resultant, selecting the first card in our Cards array.
By calling evalWith, we find that after the transition we now have a unit in our resultant, which is exactly what we need for applyMove, allowing us to just chain it in and apply those transactions, as we see here by calling exitWith to peek at our state.
Now that we have a working flow, we can remove this argument and use composeK to combine our Kleislis into one Kleisli with applyMove coming after selectCard. Now we rid ourselves of this junk in our trunk and save it down to verify we're all good. Then we'll peep the resultant to find our expected unit.
By combining all three of these distinct transactions, we now have one transition that we can use with a single Redux action.