Substitute State Using Functions With A State Monad

Share this video with your friends

Send Tweet

We take a closer look at the get construction helper and see how we can use it to lift a function that maps the state portion and updates the resultant with the result. Using get in this fashion, we then demonstrate how we can make accessors that can then be extended to create more complex interactions.

As there are times that we only want to pull the resultant for a given computation, we take a look at running our instances with the evalWith method. evalWith will run our computations, throwing away the state, returning the resultant.

Dev
Dev
~ 7 years ago

Three videos in and I still have no idea why would anyone use that…

Ian Hofmann-Hicks
Ian Hofmann-Hicks(instructor)
~ 7 years ago

@Dev

Three videos in and I still have no idea why would anyone use that…

There are many uses for it. You can reach for it when you need to combine computations that update or read from some shared state. Think of things like Redux application state or a pure random number generator, or all functions that work on some record type in a database.

When you see that a family of functions (reducers, rng seed, or user records from a database) that need to update or modify a shared state, you typically need to hold that state internally or provide it as a global in a file some where.

In the case of working on say a User record, you may have MANY operations that read from that record type or modify it in some way (changePassword, validatePassword, updateName, getEmail, etc). most of these functions either work on a shared copy or have to pass user around if you are taking a more functional approach. In these functions there tends to be a lot of destructuring off of the recordType to read from that "state", "restructuring"/merging to update that "state". This can appear all over related functions.

So what State can provide is a means to abstract away all of that state management into a simple pattern that lets your functions just focus on the computation part and not the management. Turns functions like updateName :: String -> User -> User to only care about the context and not the state, it then becomes updateName :: String -> State User ().

This initial course, mostly focuses on what is going on internally with the State datatype, and give an introduction to the API. I am working on a course now as a follow up to this that will demonstrate how to use State with Redux which will provide more of the Why. This is more the What.

Roman Kuba
Roman Kuba
~ 7 years ago

What I miss in this videos so far is a little background information. It has a lot of assumptions that it's clear why the getter functions are called fst and snd (Probably first and second) but why aren't they named first and second then or getState getValue. If one has never heard of crocks it's also hard to guess what comes in from where. To me it so far mostly feels like "This is how you follow a recipe" but I miss the explanatory parts that allow to execute upon the presented code.

I think you present it in a good way, just some more clarification about why to do some of the things would be great. <3

Ian Hofmann-Hicks
Ian Hofmann-Hicks(instructor)
~ 7 years ago

@Roman Sorry about the :corn:fusion there. I kept most of those details out of these lessons because they are more about Pair then State, but as State is a Product Type, we needed to touch on it a bit. I would like to do a course on Pair as it is an amazing type, so I will more than likely address those bit within that context.

... clear why the getter functions are called fst and snd ...

They come from the names of (2) functions in Haskell, which can be found here. I kept them the same in crocks.

... (Probably first and second) ...

in crocks first and second are methods used on two other types (Arrow and Star), you can see their documentation on Arrow here if you are curious, but I warn you, if you are not familiar with ADTs these may seem super duper :corn:fusing

... but why aren't they named first and second then or getState getValue.

Pair is it's own type, while state and resultant/value are specific meanings for State. These first few lessons use the "raw" Pair methods for extraction, but as we progress through the course we will use the State specific functions evalWith and execWith.

... To me it so far mostly feels like "This is how you follow a recipe" but I miss the explanatory parts that allow to execute upon the presented code.

I thought providing all of that context in these lessons would cloud the intent and people would seek out things that they felt were gaps in their understanding. These initial lessons are meant to show the learner what is going on inside of the datatype, and that there is not really any magic going on when we get into some of the other "helper" methods.