The problem you're having is due to the variety of ways that in Scala functions can be defined. First there are the "normal" non-curried functions with a signature like (T1, T2, ...) => RetType.
Then there are curried functions of the form T1 => T2 => ... => RetType which is essentially a chain of higher order 1-argument functions returning other 1-argument functions and the end of the chain returns the actual return value. For why this is useful, google for something like "scala curried functions".
The expression _ <someoperator> _ <someoperator> _ ... returns non-curried functions because those are the default in Scala. Therefore, if you declare foo to be returning T1 => T2 => ... => RetType but you actually return (T1, T2, ...) => RetType, the type signatures will mismatch and scalac will complain.
The solution is to either use both a curried signature as well as a curried function as the return value:
def foo1[T]: List[T] => List[T] => List[T] =
a => b => a ++ b
or use an uncurried signature and an uncurried return value:
def foo2[T]: (List[T], List[T]) => List[T] =
_ ++ _
the latter of which is the equivalent of:
def foo2[T]: (List[T], List[T]) => List[T] =
(a, b) => a ++ b
Yet another alternative is to have Scala convert your uncurried function into a curried one:
def foo2[T]: List[T] => List[T] = (_ ++ _).curried
...but, due to reasons that are out of the scope of this question, the type inferencer won't be able to be of much use, so you have to annotate and lose the concise nature of _ in the first place:
def foo2[T]: List[T] => List[T] = ((_: List[T]) ++ (_: List[T])).curried