Skip to content

Instantly share code, notes, and snippets.

@dino-
Created December 24, 2018 19:40
Show Gist options
  • Save dino-/347b0f02c4acf9053ae4ff05ca891a55 to your computer and use it in GitHub Desktop.
Save dino-/347b0f02c4acf9053ae4ff05ca891a55 to your computer and use it in GitHub Desktop.
State in Haskell is simple
#!/usr/bin/env stack
-- stack --resolver lts-12.24 script
-- If stack isn't installed on your system and you can't/won't get it, install
-- a reasonably-modern GHC and use this instead of the above two lines:
-- #! /usr/bin/env runhaskell
import Control.Monad.State
main :: IO ()
main = do
{-
We've seen examples of how to build up the State monad by hand which is
helpful to understand what's happening under the State monad covers.
I wanted to illustrate just how minimal and simple it is to use the state
monad in real world code.
-}
let startingState = 0
let result = runState ( do
addFive
multThree
) startingState
-- This code is operating entirely on the state, the return value, in the
-- left side of the tuple, is in this case a useless () value that we'll drop
print . snd $ result
{-
One case for using the State monad is that you're going to need the state
in some functions that this computation will call (signified here by
addFive and multThree) and passing it around explicitly will be ugly.
There are other reasons you may want State monad specifically but it's not
for everything.
-}
-- Sometimes a stateful task is too trivial for even that much code.
-- In simple cases, function composition will suffice
print $ (* 3) . (+ 5) $ 0
-- Another example uses a right fold and the function application function to
-- thread the state through a list of functions.
print $ foldr ($) 0 [(* 3), (+ 5)]
-- All three of these examples output the same value
-- Functions that need the state above, no need to pass explicitly
addFive :: State Int ()
addFive = do
n <- get
put $ n + 5
multThree :: State Int ()
multThree = modify (* 3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment