simulation :: Simulation ()
simulation = do
  finished <- Set.null <$> use unprocessed
  if finished
    then return ()
    else do (o, unprocessed') <- Set.deleteFindMin <$> use unprocessed
            unprocessed .= unprocessed'
            beenRemoved <- Set.member o <$> use removed
            when (not beenRemoved) $ do
              o' <- process o
              processed' <- Set.insert o' <$> use processed
              processed .= processed'
            simulation
simulation :: Simulation ()
simulation = do
  finished <- Set.null <$> use unprocessed
  if finished
    then return ()
    else do (o, unprocessed') <- Set.deleteFindMin <$> use unprocessed
            unprocessed .= unprocessed'
            beenRemoved <- Set.member o <$> use removed
            when (not beenRemoved) $ do
              o' <- process o
              processed' <- Set.insert o' <$> use processed
              processed .= processed'
            simulation
simulation = do
  finished <- Set.null <$> use unprocessed
  if finished
    then return ()
    else do (o, unprocessed') <- Set.deleteFindMin <$> use unprocessed
            unprocessed .= unprocessed'
            beenRemoved <- Set.member o <$> use removed
            when (not beenRemoved) $ do
              o' <- process o
              processed' <- Set.insert o' <$> use processed
              processed .= processed'
            simulation