Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: How to call trim on every element of a Tuple

Tags:

tuples

scala

I need to write a function that takes a Tuple of String of any size, call trims on each element and returns a new tuple. I am kind of stuck at this point below and the code is already not type safe. In addition I do not know how to go back to a tuple once I convert it to an Iterator. Is there a more elegant way to solve this problem? The solutions needs to work on Scala 2.9.2

  def trim(input:Product)={
    input.productIterator.asInstanceOf[Iterator[String]].map(_.trim)
  }
like image 616
Mansur Ashraf Avatar asked May 09 '13 21:05

Mansur Ashraf


1 Answers

If you're willing to go with a solution that uses Shapeless, this is pretty straightforward (in Shapeless terms, at least):

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's statically typed appropriately, and if you try to feed it a tuple with any non-String elements, you'll get an error at compile time.

Without a library like Shapeless—which effectively packages all the boilerplate up for you—you're stuck with two options: give up type safety, or write a special case for every tuple size you care about (up to the maximum of 22).

like image 123
Travis Brown Avatar answered Sep 21 '22 10:09

Travis Brown