I echo the sibling comments to my comment here.
I would further add that in day-to-day code, I don't necessarily write "pure" functions. I use a strategy based on my experiences with Haskell, but spiced with a bit more pragmatism. For any significant bit of code past a couple of screens or so, I almost always have a clean separation between the "business logic" code, and the "IO" code, such that I can plug different "IO" codes into the business logic code trivially.
The business logic code is not technically "pure", in that it calls out to IO code freely. But it means I can swap out the IO code for testing, and drive the business logic with any input I desire in the process. It also lets me test the IO code directly if that is useful/necessary/desirable, without the business logic getting in the way, which it often does!
Theoretically, you could transform this to "pure" code, by gathering everything into one big data structure in the IO code, then feeding it to the business logic, but this often comes with a lot of inconvenience and even performance issues (like gathering expensive things you might need but not using them).
One of the things that Haskell can "put into your fingers" is a sense of what code does IO. Even if you nominally know, you probably don't instinctively know if you've never used a language that rigidly forced you to be correct. It is a common experience for quite a while in Haskell to write a pure function, that calls a pure function, that calls a pure function... that, err... needs to read just a little bit from a file according to the way you've structured things. Whoops. And you learn to restructure things to move the reading back "up" in the code to constrain the purity, even though it's just a "little bit", and over time you get better at not making the mistake in the first place. If you are not trained by Haskell, it is really easy to end up thinking "oh, it's just a little bit of impurity... it'll be fine"... and maybe, in fact, it will. But this still starts to add up. I still write "impure" code... but I do so much more carefully now.