What makes it easier is immutability - if given an empty list, the only place that could've made this list empty is the place it was constructed - because there's no way some other function can come and delete items from it. A function which "removes" items from a list doesn't actually do such thing - it creates a brand new one and adds all the same elements except the items you requested being removed.
In this way, there's only one possible path that the list could've come from - through the pure functions which use it - until head is reached. Given that each function is referentially transparent, applying the same input list to a function in the debugger will always produce the same result, so it's simple to call a function with some sample data in ghci, and the result you get will be the same result you get in the compiled program.
Debugging/tracing is perhaps more difficult than with tooling you might already be familiar with - but it's much more rare that you need to even use them, because it's obvious what values a function should return - they don't have any state which could influence otherwise.
And there is a billion ways how to construct an empty list. You can't just grep for '[]'. It can be hidden inside of a 'catMaybes', 'tail', or any other function which returns a list and makes no guarantees about it's size, of which there are plenty.
In this way, there's only one possible path that the list could've come from - through the pure functions which use it - until head is reached. Given that each function is referentially transparent, applying the same input list to a function in the debugger will always produce the same result, so it's simple to call a function with some sample data in ghci, and the result you get will be the same result you get in the compiled program.
Debugging/tracing is perhaps more difficult than with tooling you might already be familiar with - but it's much more rare that you need to even use them, because it's obvious what values a function should return - they don't have any state which could influence otherwise.