How do you define state in Haskell? My first idea was to use algebraic data types. I've also heard about the state monad, but I don't really know what it is. As an example, lets use Texas hold'em poker. We have to represent the following states:
Each line where we call a function "in the state monad" behaves as follows: the arguments we give it on that line are applied, yielding a partially applied function. This is because each of the state monad functions yields a State function (which still needs an argument of type s before it can yields it's result tuple.
A monad is an algebraic structure in category theory, and in Haskell it is used to describe computations as sequences of steps, and to handle side effects such as state and IO. Monads are abstract, and they have many useful concrete instances. Monads provide a way to structure a program.
A proper monad must satisfy the three monad laws: left identity, right identity, and associativity. Together, left identity and right identity are know as simply identity.
The Reader monad (also called the Environment monad). Represents a computation, which can read values from a shared environment, pass values from function to function, and execute sub-computations in a modified environment. Using Reader monad for such computations is often clearer and easier than using the State monad.
There are two parts to using state in Haskell. The first one is just modeling and creating Datatypes to represent your things (just like in any other language). For example:
data Card = NumberCard Int | Jack | Queen | King | Ace
type Hand = (Card, Card)
data Player = Player Hand Int --a hand and his purse
data Action = Fold | Check | Bet Int | Raise Int
type Deck = [Card]
type TableState = ([Player], Deck)
--and functions to manipulate these, of course...
Then there is the part of how you use this state. You don't need to know monads to start making stuff (and you should only bother with the advanced topics when you have the basics mastered anyway). In particular you don't really need to use "state", you just need to receive and return these values in functional style.
For example, a round would be a function that takes a table state (list of players and the deck), a list of player actions and returns a new table state (after the roud had been played given these actions).
playRound :: TableState -> [Action] -> TableState
playRound (players, deck) actions = ...
Of course it is now your responsibility to make sure that the old table state is forgotten after you create a new one. Things like the State monad help with this kind of organizational issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With