someFunc :: MaybeT IO ()
To be consistent with the advice below, rewrite someFunc :: (Alternative m, MonadIO m) => m (). This is not needed for implementing someFunc, but is needed for using someFunc in other operations without explicit lifting when the other operations are not specifically in the MaybeT IO monad.
someFunc = do
foo1 <- MaybeT $ ...
Rewrite ... to use return and empty instead of return . Just and return Nothing.
foo2 <- MaybeT . return $ ...
Rewrite ... to use return and empty instead of Just and Nothing.
foo3 <- lift $ ...
For MaybeT IO, the lift and liftIO operations are identical, so see the next suggestion. In the general case (rather than specific to MaybeT IO), rewrite ... to be typeclass polymorphic for a class that your concrete monad inhabits.
foo4 <- liftIO $ ...
Can't do much about this. Sometimes it is possible to give ... a MonadIO constraint rather than an IO type. Usually that just shifts the location of the liftIO, though; it has to appear somewhere.