No, that does not make sense. Rust's unsafe code lets you do some things that could violate the compiler's expectations, and making sure that you're aware that you need to manually enforce those invariants. Haskell has some unsafe* functions that are exactly like that, too, such as unsafePerformIO, that are analogous. On the other hand, the IO and State monads are completely safe-to-use, using a simple abstraction to represent impurity in a pure language.
- IO can be seen as a tag added to a type that brings »the outside« into scope: the console, the network, current time, the harddrive. In Rust, these are always available, regardless of the type of the expression at hand.
- IO is »viral«, in the way that things that touch IO will become IO as well; there is no way to remove IO to yield a pure value. If a function in Rust contains an unsafe block, is the whole thing unsafe? I don’t know enough Rust, but I think it’s not.
unsafe is not viral; if it was, everything would be unsafe. An unsafe block is the boundary where you tell the compiler "I've got this bit", and so it trusts you and considers it safe.