We have implemented two very commonly used higher order functions in Haskell. You will notice subtle differences between recursive and tail-recursive functions. There is another important difference that must be highlighted. The non-tail-recursive version of map and filter can work with the infinite list because the first element is evaluated and the rest of the list is evaluated only when it is required. In, for the tail-recursive version, the whole list has to be evaluated, as we need to push the whole list in to the result argument and then reverse it.
You can also refer to the Hackage source of Data.List and its implementation of map and filter.