Search code examples
scalashapeless

How to append or prepend an element to a tuple in Scala


I have a tuple and want to add an element without loosing type safety. This is what I want to achieve:

val tuple = ("", 1, 1f) // (String, Int, Float)

val newTuple:(String, Int, Float, Double) = tuple :+ 1d

Solution

  • It's worth noting that you can also write a code generator for this in a few lines:

    val tupadd = for (n <- 2 to 20) yield {
      val t = (0 until n).map(i => ('A'+i).toChar).mkString(", ")
      val u = ('A'+n).toChar
      val i = (0 until n).map(i => "x._"+(i+1)).mkString(", ")
      List(
        s"implicit class TupOps$n[$t](val x: ($t)) extends AnyVal {",
        s"  def :+[$u](y: $u) = ($i, y)",
        s"  def +:[$u](y: $u) = (y, $i)",
        "}"
      ).mkString("\n")
    }
    

    Print these out, stick 'em in a file, and you're good to go:

    scala> implicit class TupOps2[A, B](val x: (A, B)) extends AnyVal {
         |   def :+[C](y: C) = (x._1, x._2, y)
         |   def +:[C](y: C) = (y, x._1, x._2)
         | }
    defined class TupOps2
    
    scala> (1,"salmon") :+ true
    res15: (Int, String, Boolean) = (1,salmon,true)