Other programming traditions also have this pattern of inventing minilanguages and interpreters for them; regular expressions are by far the most successful example. You could hand-roll string matching by writing your matching functions by hand, but it's often much easier to ask a regex library to run an interpreter over a string describing the pattern to match.
In Haskell, it's really cheap to invent data structures, so using the same language to describe the work is quite convenient. Laziness also means you almost never materialise the entire intermediate "work to be done" structure - you build little bits as the interpreter demands them. So it doesn't feel as heavyweight as an eDSL in some other language.