Haskell game server auth: cookie key generate&check
As modifyIORef notes, use modifyIORef' for counters.

I would wrap the unsafe usage of unsafePerformIO into a safer interface.

withCounter :: (Int -&gt; IO a) -&gt; IO a
withCounter action = let counter = unsafePerformIO $ newIORef 0 in do
  i &lt;- readIORef counter
  modifyIORef' counter (+1)
  action i

generateId = withCounter $ \date -&gt; do
  time &lt;- fromEnum . utSeconds &lt;$&gt; getUnixTime
  return $ time * 1000 + mod date 1000


The || logic doesn't seem to be in the Haskell code yet.

I wouldn't give a name to a private function used only once.

Many of your brackets are redundant. The hint tool can tell you this.

It seems you want to use some but not all of what you define in other code. The code that uses this could make a difference in the review.

Data.Unique may interest you for id generation if you do not actually care about your exact behavior.