Formatting as a table in Scala I'm trying to get my head in the Scala game, and would welcome feedback on the following code, which produces a table from data.

class TabulatorTest extends FunSuite with ShouldMatchers {

  test("format") {
    Tabulator.format(List(
      List("head1", "head2", "head3"),
      List("one", "two", "three"), 
      List("four", "five", "six"))) should be ("""
+-----+-----+-----+
|head1|head2|head3|
+-----+-----+-----+
|  one|  two|three|
| four| five|  six|
+-----+-----+-----+
""".trim)
  }

  test("format empty") {
    Tabulator.format(List()) should be ("")
    Tabulator.format(List(List())) should be ("""
++
||
++
++
""".trim)
  }

  test("uneven rows") {
    try {
      Tabulator.format(List(    
        List("head1", "head2", "head3"),
        List("one", "two")))
      fail()
    } catch {
      case e: IllegalArgumentException =&gt; 
    }
  }
}




object Tabulator {

  def format(table: Seq[Seq[Any]]) = table match {
    case Seq() =&gt; ""
    case _ =&gt; 
      val cellSizes = for (row &lt;- table) yield 
        (for (cell &lt;- row) yield 
          if (cell == null) 0 else cell.toString.length)
      val colSizes = for (col &lt;- cellSizes.transpose) yield col.max
      val rows = for (row &lt;- table) yield formatRow(row, colSizes)
      formatRows(rowSeparator(colSizes), rows)
  }

  def formatRow(row: Seq[Any], colSizes: Seq[Int]) = {
    val cells = (for ((item, size) &lt;- row.zip(colSizes)) yield 
      if (size == 0) "" else ("%" + size + "s").format(item))
    cells.mkString("|", "|", "|")
  }

  def formatRows(rowSeparator: String, rows: Seq[String]): String = (
    rowSeparator :: 
    rows.head :: 
    rowSeparator :: 
    rows.tail.toList ::: 
    rowSeparator :: 
    List()).mkString("\n")


  private def rowSeparator(colSizes: Seq[Int]) =
    colSizes map { "-" * _ } mkString("+", "+", "+")
}
I can't help a lot. Only some syntactic hints:

object Tabulator {

  def format(table: Seq[Seq[Any]]) =
    if (table.isEmpty) ""
    else {
      def cellSize(cell: Any) =
        cell.toString.length

      val cellSizes =
        table map { _ map cellSize }
      val colSizes =
        cellSizes.transpose map { _.max }
      val rows =
        table map formatRow(colSizes)

      formatRows(rowSeparator(colSizes), rows)
    }

  def formatRow(colSizes: Seq[Int])(row: Seq[Any]) = {
    val cells =
      for ((item, size) &lt;- row zip colSizes) yield
        if (size == 0) "" else "%"+size+"s" format item
    cells mkString ("|", "|", "|")
  }

  def formatRows(rowSeparator: String, rows: Seq[String]): String = (
       rowSeparator
    :: rows.head
    :: rowSeparator
    :: rows.tail.toList
    ::: rowSeparator
    :: Nil
  ) mkString "\n"


  private def rowSeparator(colSizes: Seq[Int]) =
    colSizes map { "-"*_ } mkString ("+", "+", "+")
}


I deleted the null-check in cellSize because null is not familiar in Scala. If you definitely need null then restore the check.