There's no strict definition of a combinator, so it doesn't really mean anything in that sense. However, it is very common in Haskell to build more complex functions or values out of simpler ones, and sometimes functions doesn't fit together completely, so we use some glue to make them stick together. The bits of glue we use to do that we call combinators.
For example, if you want to compute the square root of a number rounded to the closest integer, you can write that function as
approxSqrt x = round (sqrt x)
You may also realise that what we are really doing here is taking two functions and building a more complex function using them as building blocks. We need some kind of glue to put them together, however, and that glue is (.):
approxSqrt = round . sqrt
So the function composition operator is a combinator of functions – it combines functions to create new functions. Another example is that perhaps you want to read each line of a file into a list. You could do this the obvious way:
do
contents <- readFile "my_file.txt"
let messages = lines contents
...
But! What would we do if we had a function that reads a file and returns the contents as strings? Then we could do
do
messages <- readFileLines "my_file.txt"
...
As it turns out, we have a function that reads a file and we have a function that takes a big string and returns a list of the lines in it. If we only had some glue to stick those two functions together in a meaningful way, we could build readFileLines! But of course, this being Haskell, that glue is readily available.
readFileLines = fmap lines . readFile
Here we use two combinators! We use the (.) from before, and fmap is actually a very useful combinator as well. We say that it "lifts" a pure computation into the IO monad, and what we really mean is that lines has the type signature
lines :: String -> [String]
but fmap lines has the signature
fmap lines :: IO String -> IO [String]
so fmap is useful when you want to combine pure computations with IO computations.
These have just been two very simple examples. As you learn more Haskell, you'll find yourself needing (and inventing) more and more combinator functions for yourself. Haskell is very powerful in the way you can take functions and transform them, combine them, turn them inside out and then stick them together. The bits of glue we sometimes need when we do that, those bits we call combinators.