You're asking for a way to update some (possibly hidden) state on each call to a procedure, such that the function returns different results given the same input.
Clearly, that's no a referentially transparent function, so we must add something to Haskell's pure-by-default mode. We add notions of computation via monads. You just have to pick the monadic environment you need.
The state monad
The most precise way is to add just exactly the notion of state to your program, via the State monad (not to be confused with the "ST" monad):
import Control.Monad.State.Strict
-- a (stateful) procedure, that returns and increments an internal state counter
f :: State Int Int
f = do
n <- get
put (n+1)
return n
-- Call 'f' a bunch of times, print the final state.
main = print $ execState code 0
where
code = do f; f; f; f
Now 'f' has an internal state component.
Similarly, richer environments, such as IO, allow for State, so you could use the IO monad (or some other state-subsuming computational environment).