The reason is because the operator $= puts together a source and a conduit and returns a new source.
The operator =$= is used to combine two conduits into another conduit.
With $= if you try to put two conduits together, the underlying types just won't match up. They don't match up specifically to tell you that you are not quite doing it correctly. It is trying to match the first argument to a source, which has its input type restricted to (). Since you have a string there, then it complains.
So try display = CL.iterM putStrLn =$= CL.iterM putStrLn which does exactly what you were looking for.