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.


    Draw Items from One JavaScript Array to Another using a Pair ADT


    We want to be able to pick nine random cards from an array of twelve cards, but can run into problems of keeping both the cards already draw and the cards left to draw from. Tracking two bits of state like this can create some hard to maintain argument gymnastics when creating our functions. Luckily we have a datatype Pair at our disposal that allows us to combine two values in to one value.

    We will use this Pair type to model both a draw pile and a remaining pile, and take advantage of a couple special properties of Pair that will allow us to combine two Pair instances in a meaningful way by chaining. Just like we have done time and time again with the State ADT



    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 have this generate cards function that uses both the colors and shapes attributes in our state to generate a list of 12 cards. When called, it returns an instance of the state ADT.

    We can run this instance with the val width by passing in our initial state to see that it deposits the expected list in the resultant. Checking the length tells us that all 12 cards are present and accounted for.

    We would like the ability to model the drawing of a card by defining a deck type that uses a pair to represent two piles of cards -- 8 cards drawn on the left and the remaining cards on the right. With our deck type defined, we'll implement the act of drawing a card from a specific location in the form of a function called drawCard at that takes an index as its first argument. We define drawCard at as a curried function that takes an integer to a function that takes an array of card to our newly defined deck type.

    We use the croc's fan-out function to generate our pair by using this getAt helper function on the left to select a card from an array at a given index. Partially applying our desired index gives us a function ready to accept an array.

    For the right side, we'll reach for this unset at function that removes a card from a specified location, also applying our index as its first argument, leaving us with a function that'll take an array of card to a pair representing our deck.

    To see this in action, we'll import it into our index file and use the array in our resultant that we get from generate cards, by mapping our new drawCard at function, partially applied with zero to draw the top card, getting back our expected deck.

    We find our remaining cards in the second or right side of the pair with a length of 11, and in the first, we see our top card, but only our top card.

    If we look at the siggy for deck, we wanted an array of card on the left, not just a single card. Because pair is a bifunctor, it means we can use bimap to map both sides in one fell swoop -- with array.of on the left, and leave the right side untouched by using identity.

    Composing this with the original function, we now get what we're looking for. We can even draw the 8 card by passing 7 as our index, pulling this blue triangle.

    When a semigroup, like array, inhabits the left portion of a croc's pair, we can chain on the right side, resulting in a new pair with the values on the left concatenated, as we see here with the first and third cards.

    Each time we chain, our right value is replaced with the right side of our resulting calculation, leaving only 10 cards remaining. Drawing another card leaves us with 9 cards remaining on the right. The left comfortably holds our 3 freshly drawn cards.