Referential transparency is a good property for functions that are internal to your program because it makes it easier to understand what the code does. Functions that interact with the outside world (eg with a database) can not have referential transparency.
The Haskell core is a purely functional language. But a purely functional program in Haskell in reality are just instructions to build a program, and the program that is built that way has side effects. This is what type IO ()
means: instructions to build a program whose execution has no referential transparency.
The Erlang project is a good example here. In Erlang, programs are made up of processes that exchange messages. The process language has referential transparency, but the way processes process messages do not, because when a process sends a message, the recipient watches this action.