- You can't print to the screen
- There's no reserved memory for variables
The only thing that a function can do is return a value
- We're not allowed to print to the screen
- We can't do I/O
- File I/O
- Network I/O
 
How can Haskell do stateful operations without breaking the expecations of how functions work?
Let's look at this stateful version of fibonacci in Java:
public static int fibonacciLoop(int nthNumber) {
	int previouspreviousNumber, previousNumber=0,
	currentNumber = 1;
	for (int i = 1; i < nthNumber; i++) {
		previouspreviousNumber = previousNumber;
		previousNumber currentNumber;
		currentNumber = previouspreviousNumber + previousNumber;
	}
	return currentNumber;
}Let's try to convert it to Haskell.
First we need a way to represent the state:
data FibState = FibState {
	previousNumber :: Integer,
	previouspreviousNumber :: Integer,
	currentNumber :: Integer
}
type FibStateful a = FibState -> (FibState, a)
-- getPreviousNumber :: FibState -> (FibState, Integer)
getPreviousNumber :: FibStateful Integer
-- `previousNumber oldstate` how we access named fields
getPreviousNumber oldstate = (oldstate, previousNumber oldstate)
-- an empty tuple is the Haskell way of saying `void`
-- setPreviousNumber :: Integer -> FibState -> (FibState, ()) 
setPreviousNumber :: Integer -> FibStateful ()
setPreviousNumber newval oldstate =
	(newstate, ())
	where newstate =
		FibState {
			previousNumber = newVal,
			previouspreviousNumber = previouspreviousNumber oldstate,
			currentNumber = currentNumber oldstate
		}
Now we can make our program:
module Fib where
import FibStateful
-- repeatTimes :: Integer -> (FibState -> (FibState, a))
				-> (FibState -> (FibState, a))
-- repeatTimes numberofTimes statefulFunction state
repeatTimes :: Integer -> FibStateful a -> FibStateful a
repeatTimes 0 _ _ = error "Can't do that"
repeatTimes 1 f state = f state
repeatTimes n f state = 
	let (newstate, x) = f state
		in repeatTimes (n-1) f newstate
fib :: Integer -> Integer
fib n =
	let (finalstate, answer) = fibAlgorithm n initialState
	in answer
	where initialState :: FibState
		initialState = FibState = FibState {
			previousNumber = 0,
			previousPreviousNumber = 0,
			currentNumber = 1
		}
fibAlgorithm :: Integer -> FibStateful Integer
fibAlgorithm n oldstate =
	repeatTimes n (\s -> 
		let (state1, pn) = getPreviousNumber s
			(state2, ()) = setPreviousPreviousNumber pn state1
			(state3, cn) = getCurrentNumber state2
			(state4, ()) = setPreviousNumber cn state3
			(state5, pn') = getPreviousNumber state4
			(state6, ppn) = getPreviousPreviousNumber state5
			(state7, ()) = setCurrentNumber (pn' + ppn) state6
		in getCurrentNumber state7
	) oldstateWe can simulate statefulness by making a function that takes in state and returns state
Let's refactor fibAlgorithm by creating a helper function bind that automatically gets, sets and passes state to the next
bind :: FibStateful a -> (a -> FibStateful b) -> FibStateful b
bind f g s = 
	let (newstate, value) = f s
	in g value newstate
fibAlgorithm :: Integer -> FibStateful Integer
fibAlgorithm n =
	repeatTimes n (\s -> 
		getPreviousNumber `bind`
		setPreviousNumber `bind` \_ -> 
		getCurrentNumber `bind`
		setPreviousNumber `bind` \_ ->
		getPreviousNumber `bind` \pn ->
		getPreviousPreviousNumber `bind` \ppn ->
		setCurrentNumber (pn + pnn)
		in getCurrentNumber
	)