1. 2
    Define Discrete State Transitions using the State ADT
    3m 42s

Define Discrete State Transitions using the State ADT

Share this video with your friends

Social Share Links

Send Tweet
Published 5 years ago
Updated 5 years ago

We build our first state transactions as two discrete transactions, each working on a specific portion of the state. Each of these transitions are governed by an acceptable range and we want to be able to apply these limit within our model.

With our discrete transactions we see that is easy to reason about and keeps our rules local to the data being worked on, without having to be considered in other transitions or, even worse, in the eventual view layer. Patterns like this make it easier to easily transport a given data model to any view layer.

Instructor: [00:00] We have two attributes in our state. The first represents the number of moves left, while the second tracks the number of moves the player has made. Here, we're just kenny-loggings our state to the console on the right.

[00:11] Let's start building out some transactions in our answer model. We'll start by creating a limiting function that will keep stray values in check. We'll call it limitMoves. limitMoves is defined as a function that takes a function from A to number as its first argument, giving back another function that takes an A and returns us a number.

[00:32] To implement, we'll reach for this clampAfter helper, applying zero and eight is its arguments. Then we'll just pop over to helpers and see what it does. Looking at the siggie, we see our first two numbers followed by the A-to-number function, then the same A-to-number function from limitMoves.

[00:49] We take a min and a max value followed by a function and return a composition that runs that function, passing the result to a clamping function, thus limiting our number. We'll export our first transaction that will decrement our moves left when the player performs a move.

[01:06] We define our brand-new decLeft to be a function that goes from a unit to a state fixed to our appState with a unit in the resultant. To implement, we first take our unit as input. Then we'll lean on this over helper to decrement over our left attribute using limitMoves, which we preload with this dec helper.

[01:29] Over can be thought of as a targeted mini-reducer for applying a function over a state attribute. It takes a pair of string function and then an object returning a state object of unit. Using the key and function, we build an object that partially applies mapProps to be used with our state's modify function.

[01:50] In this case, the function we're going to apply is this dec function. It takes a number to number and just subtracts one from our input, returning the result. After a quick save, we'll take this for a spin by importing it into our index file by referencing decLeft from our file, which we pull from the path data model answer, from which it was exported from.

[02:15] With another quick save, we take a stroll downstairs and log out a call to decLeft, calling it with unit. We see we get back a state instance. We run the instance with execWith, passing it our initial state. We see that left has indeed been decremented.

[02:30] We can chain in another call to decLeft to decrement again. Because of our clamps -- insert "Futurama" reference -- we can chain so much and never go below zero. We can even start at a zero state and be assured that we'll only have the values within the range we desire, no matter how it's called.

[02:49] With decLeft in the bag, we'll reset our initial state and do something similar for our moves attribute, so similar in fact that we'll copypasta decLeft and then update the name, the function used with limitMoves, and the key we want to modify.

[03:04] We rename it to incMoves in both the signature and the actual function name. Change left to moves. Finally, replace dec with inc. In order to test this, in our index file, we swap out decLeft with incMoves in our import statement, as well as down below in our logging function, and observe our moves being incremented.

[03:27] Just like decLeft, we can chain incMoves and get the expected behavior for one chain or by chaining as many as we want without any worry about these values stepping outside of our desired limits.

zarcode
zarcode
~ 5 years ago

The over function works good on changing direct props of state object. Need help on how to change props of nested object inside of state?

Ian Hofmann-Hicks
Ian Hofmann-Hicksinstructor
~ 5 years ago

The over function works good on changing direct props of state object. Need help on how to change props of nested object inside of state?

It really all depends on your structure, without information about your domain it is hard to make a specific suggestion. But the beauty of over in this case is that it takes a function and will return the value at your specified key. If that value is an object then you can use mapProps, loaded with your change. Or you can use the ramda lens functions if you have a lot of nested data at a specific key.

The only real point of over is to merge your state transition at a specific scope, you can do whatever you need to do with the function you provide it.

zarcode
zarcode
~ 5 years ago

Got it. Thank you! Love the course.

Jonathan Stiansen
Jonathan Stiansen
~ 5 years ago

It looks like we should just be using reasonML for this... ;-) Loving this idea btw, going into my training for new employees.

Daniel Lopez
Daniel Lopez
~ 5 years ago

Why, when you call a function without arguments, you say "calling with unit"?

Ian Hofmann-Hicks
Ian Hofmann-Hicksinstructor
~ 5 years ago

Why, when you call a function without arguments, you say "calling with unit"?

That is the Type, notice that it looks like an empty tuple (). That can be considered a singleton Set or a Set with one element in it, which is undefined

Markdown supported.
Become a member to join the discussionEnroll Today