Join egghead, unlock knowledge.

Want more egghead?

This lesson is for members. Join us? Get access to all 3,000+ tutorials + a community with expert developers around the world.

Unlock This Lesson
Become a member
to unlock all features

Level Up!

Access all courses & lessons on egghead today and lock-in your price for life.


    Compose Simple State ADT Transitions into One Complex Transaction


    State is a lazy datatype and as such we can combine many simple transitions into one very complex one. This gives us a lot of control over how our state changes over time. In this lesson we will use this to our advantage and combine many transactions into one complex action. In the end only the final state will be reported which can be reasoned about as one transition.



    Become a Member to view code

    You must be a Pro Member to view code

    Access all courses and lessons, track your progress, gain confidence and expertise.

    Become a Member
    and unlock code for this lesson
    orLog In




    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.