If you want to go with a solution that uses Shapeless , it's pretty simple (at least in formless terms):
import shapeless._ object trimmer extends (String -> String)(_.trim) def trim[T <: Product, L <: HList](t: T)(implicit hlister: HListerAux[T, L], toList: ToList[L, String], mapper: MapperAux[trimmer.type, L, L], tupler: TuplerAux[L, T] ) = hlister(t).map(trimmer).tupled
And then:
scala> trim((" a ", "b ", " c")) res0: (String, String, String) = (a,b,c) scala> trim((" a ", "b ", " c", "d")) res1: (String, String, String, String) = (a,b,c,d)
Everything is statically typed correctly, and if you try to feed it with a tuple with any non- String elements, you will receive an error message at compile time.
Without a library, such as Shapeless, which effectively packs all the templates for you, you are stuck in two ways: refuse the type of security or write a special case for each size of your tuple that you care about (maximum 22).