It is definitely not procedural.
"This seems rather … procedural. Even though we get all the nice guarantees of working with side effectful functions in Haskell, the code itself reads like any other procedural language would. With Haskell, we get the best of both worlds."
Working with the IO monad is much more complex, especially if you want to use other monadic types inside that code.