Получается так, что в Haskell’е заново изобретено императивное программирование...
В некотором смысле — да. Монада IO встраивает в Haskell маленький императивный подъязык, при помощи которого можно осуществлять операции ввода/вывода. И написание программ на этом подъязыке выглядит обычно с точки зрения императивных языков. Но есть существенное различие: в Haskell’е нет специального синтаксиса для ввода в программный код императивных функций, все осуществляется на уровне функциональной парадигмы. В то же время опытные программисты могут минимизировать императивный код, используя монаду IO только на верхних уровнях своих программ, т.к. в Haskell’е императивный и функциональный миры чётко разделены между собой. В отличие от Haskell’а в императивных языках, в которых есть функциональные подъязыки, нет чёткого разделения между обозначенными мирами.