tags:

views:

181

answers:

2

Hello to everyone. I came across with an error on my Scala code that I cannot solve by myself (I am new at Scala). I have the following code:

def myFunction(list: List[Any]): String = {
  var strItems : String = "";
  list.foreach(item => {
    strItems += item match {
      case x:JsonSerializable => x.toJson()
      case y:String => ("\"" + y + "\"")
      case _ => item.toString
    }
    if(item != list.last)
      strItems +=  ",";
  })
  strItems;
}

The error I am getting is:

error: pattern type is incompatible with expected type; found : String required: Unit case y:String => ("\"" + y + "\"")

Any idea why?

PS: is there a more performant way to code myFunction

A: 

Here's a form of your code that compiles (w/o any definition for JsonSerializable) (in Scala 2.8) along with a more succinct formulation (that also happens to be point-free):

object Javier01 {
  def
  javFunc(list: List[Any]): String = {
    val strItems = new StringBuilder()

    list.foreach { item =>
      strItems.append ( item match {
//      case x: JsonSerializable => x.toJson()
        case y: String => "\"" + y + "\""
        case _ => item.toString
      } )

      if (item != list.last)
        strItems.append(",")
    }
    strItems.toString
  }

  def
  rrsFunc(anys: List[Any]): String =
    anys map {
//    case x: JsonSerializable => x.toJson()
      case s: String => "\"" + s + "\""
      case x => x.toString
    } mkString ","


  def
  main(args: Array[String]): Unit = {
    val stuff = List(true, 1, 123.456, "boo!")

    printf("        stuff : %s%njavFunc(stuff): %s%nrrsFunc(stuff): %s%n%n",
           stuff, javFunc(stuff), rrsFunc(stuff))
  }
}

The output from running this is:

% scala Javier01
        stuff : List(true, 1, 123.456, boo!)
javFunc(stuff): true,1,123.456,"boo!"
rrsFunc(stuff): true,1,123.456,"boo!"
Randall Schulz
+6  A: 

In terms of the original question, the code doesn't compile because it requires parentheses around the match, ie. strItems += (item match { ... })

A more "functional" way of writing this could be something along the lines of:

def myFunction(list:List[Any]):String = {
  val strings:List[String] = list.map{
    case x:JsonSerializable => x.toJson()
    case y:String => ("\"" + y + "\"")
    case z => z.toString
  }
  strings.mkString(",")
}

You could probably use a view to make it lazy and more "performant", although I don't know off the top of my head if that would combine the two underlying loops (map & mkString) into a single traversal.

Kristian Domagala
Daniel