# Haskell: State and StateT examples.

# A look at the State Monad and StateT Monad Transformer.

Beginning to work with Monads is an important aspect of learning to work with Haskell. I wanted to add my take on some simple examples to try and add to the existing ones. So let’s have a look.

## Let’s say

We have a web app and we need to monitor if a user is logged in or not across our session, and each of our functions return a result.

## The code

Firstly we need to import our monad libraries. For this example we will be using:

```
import Control.Monad.IO.Class (liftIO) -- ^ liftIO allows us to lift the output
-- out of the monad and for example
-- print or read, just like normal IO.
import Control.Monad.Trans.State -- ^ the bog standard State Monad,
-- together with the StateT Monad
-- Transformer, which allows us to
-- enrich the IO monad with the
-- capabilities of State monad.
```

OK, I will try and comment the text as I go along, but so far so good. Let’s now define our two data types that we will use, based on the above web app assumptions.

```
data WebsiteResult = OK | Err String deriving (Show, Eq)
data WebsiteState = LoggedIn | LoggedOut deriving (Show,Eq)
```

So we know that the Website can return an `OK`

or an `Err + String information`

and all the state we want to track is if we are `LoggedIn`

or `LoggedOut`

. I
hope this is all good until now. Let’s now have a look at defining an operation.

```
exOperation :: State WebsiteState WebsiteResult
exOperation = do
logIn "Password"
makeTransaction
printResult
```

Arguably you can read what the `exOperation`

does - without seeing the actual
implementation (to which we will get to) of the operations. It first tries to
login by providing a string `"Password"`

, then it attempts to make a
transaction, and at the end it prints out the result. We can agree this is very
neat. Furthermore if we look at the type of `exOperation`

we can already get an
insight into what it tells us. We read it as: *we are operating with a State
monad that is holding an instance of WebsiteState and at the end we are
returning a WebsiteResult.*

OK now let’s have a look at how we would go about implementing these operations.

```
logIn :: String -> State WebsiteState WebsiteResult
logIn password = do
if password == "Password" -- | check if it is the password
then put LoggedIn -- | logged in
else put LoggedOut -- | logged out
checkOk -- | at the end we check to see what happened
where
checkOk :: State WebsiteState WebsiteResult
checkOk = do
state <- get
if state == LoggedIn then return OK else return $ Err "Bad Log In"
```

The first one takes a String, compares it to the (albeit hard-coded here) correct
password. If it likes it, it changes the state to `LoggedIn`

by using the `put`

function. If it doesn’t then it changes it to `LoggedOut`

. At the end I provided
one more monad instance to show how we would change the return. In it we use the
other useful function for the `State`

monad, namely `get`

which gets the
`WebsiteState`

out of the monad. Hopefully you are starting to get the gist of
it, if not let’s look further at the other two functions:

```
makeTransaction :: State WebsiteState Bool
makeTransaction = do
state <- get
case state of
LoggedIn -> return True
LoggedOut -> return False
printResult :: State WebsiteState WebsiteResult
printResult = do
state <- get
case state of
LoggedIn -> pure $ OK
LoggedOut -> pure $ Err "Hi, enter your good password!"
```

These are mostly identical with the exception of one thing, namely the use of
`pure`

instead of `return`

. It’s worth keeping in mind that both are identical,
and it’s mostly to do with defining `Applicative Functor`

.

## Running the Monad

OK so all good, but how do we get the result of running the `exOperation`

monad?
Well to do this we need to use `runState :: State s a -> s -> (a, s)`

which (as
its type suggests) takes a State Monad and an initial State and returns the
result of the calculation as a tuple of state and result. Perfect so let’s do it.

```
result = runState exOperation LoggedOut -- will return (OK,LoggedIn)
```

And if we wanted to get the result only and print it we could simply feed this
to a `fst`

in a `IO ()`

monad.

```
printOutResult :: IO ()
printOutResult = print $ fst result
```

# But what if …

But what if we wanted to print out results as we went along, would that be
possible? The answer is yes, but that means that we would need access to an `IO`

monad instance while we are inside the `State`

monad, which still behaves as we
would expect `IO`

to behave. This is exactly what `StateT`

monad is for. Where
`State`

would have to have a signature of the type `State Type1 (IO Type2)`

we
can see from the signature that we don’t have (easy) access to `Type2`

- as it
is wrapped inside the `IO`

and we cannot reach inside to grab it. `StateT`

allows us to make use of a type looking like `StateT Type1 IO Type2`

- hence now
we can make use of both the `State`

functions and the `IO`

capabilities. Let’s
look at the example, which I have annotated to make it easier to follow along.

```
-- If we wanted to combine this behaviour with an IO Monad we would need to use
-- the StateT transformer.
operations :: IO ()
operations = do
putStrLn "Hello and Welcome to our Operations.\n Please insert your password:"
pass <- getLine
let computation = logInT pass
let initialState = LoggedOut
result <- runStateT computation initialState
return ()
-- | Observe how our return actually returns inside the IO Monad but our state
-- is outside of it. This offers us more control than something like "State
-- WebsiteState (IO WebsiteResult)" because we get a shallower version of the
-- monad, and we also get access to the
logInT :: String -> StateT WebsiteState IO WebsiteResult
logInT password = do
-- | First thing we get the state
state <- get
-- | Then, we check if we are already logged in.
if state == LoggedIn
then liftIO $ print "Allready Logged In!"
else liftIO $ print "You need to sign in"
-- | Now we get to check the password.
if password == "Password"
then put LoggedIn
else put LoggedOut
-- | In the end we get the state again to check if the log in was successful.
state <- get
case state of
LoggedIn -> liftIO $ print "Correct Password! Welcome!"
_ -> liftIO $ print "Bad Password. Denied."
-- | And at the end end we just return a random Auth Code.
return OK
```

Worth noting here is that we could have just used `return`

or `pure`

to lift the
`IO`

operation, but the issue here is that it will not print or read it (best
way to understand this would be to try it yourself), hence we need to use
`liftIO`

- this way we make sure that the `IO`

operations happen as expected.

## In the end

Hopefully this example helps you use `State`

and `StateT`

and gives a bit more
insight.