Hi,
I always write functions like this:

addPlayer :: PlayerInfo -> State Game Bool
addPlayer pi@(PlayerInfo {playerNumber = pn}) = do
    pls <- gets players
    case find (\(PlayerInfo {playerNumber = myPn}) -> pn == myPn) pls of
        Nothing -> do
            modify (\game -> game { players = pi : pls})
            return True
        otherwise -> return False

It simply adds a new PlayerInfo to a list contained in Game, with the condition that it doesn't exists already.
Do you see a more elegant way to do this?

Best,
Corentin