IO monad doesn't hide state, it says right in the type that it's IO. Neither do other monads that "hide" state according to you, because they actually specify that they use state right in the type signature.
OOP approach hides state because it uses private variables that might be modified in the body of the function. Yet there is nothing in the type signature that states that this function is not referentially transparent!
OOP approach hides state because it uses private variables that might be modified in the body of the function. Yet there is nothing in the type signature that states that this function is not referentially transparent!