The concept is that affecting stdout isn't "just" - it requires a clear definition
when (and
if) that function will be executed, and in Haskell you don't do that if you can avoid that - it allows for lazy execution, actually running the function less (or 0) times depending on how it's result is used.
I.e., if your program needs top 3 results in a race, then you can safely use a function that returns all the results, but since you afterwards use only first three then the remainder aren't calculated, that code most likely isn't run and the order of any "embedded" print statements would be undefined.
That being said, standard Debug.Trace module allows simple adding of debug prints anywhere.