For example, imagine that you have the following:
import play.api.data._ import play.api.data.Forms._ case class TestDomainClass(text: String, number: Int, date: DateTime, long: Long, boolean: Boolean) val testForm = Form( mapping( "textField" -> text, "numberField" -> number, "dateField" -> jodaDate, "longField" -> longNumber, "booleanField" -> boolean )(TestDomainClass.apply)(TestDomainClass.unapply) )
My goal is to match patterns by type of parameters for each of the fields. For example: for textField the parameter type will be String , and for dateField will be org.joda.time.DateTime .
First attempt to solve
def typeOfMappingUsingTypeTag[T: TypeTag](m: Mapping[T]) = typeOf[T] match { case t if t =:= typeOf[String] => println("type is String") case t if t =:= typeOf[Int] => println("type is Int") case t if t =:= typeOf[org.joda.time.DateTime] => println("type is DateTime") case t if t =:= typeOf[Long] => println("type is Long") case t if t =:= typeOf[Boolean] => println("type is boolean") case _ => println("type is something else") } for(m <- testForm.mapping.mappings if m.key.nonEmpty) { print(m.key) typeOfMappingUsingTypeTag(m) }
With the following output:
textFieldtype is something else numberFieldtype is something else dateFieldtype is something else longFieldtype is something else booleanFieldtype is something else
So no luck, which was somewhat expected, since the source Mapping does not have a binding to TypeTag.
Second attempt to solve
def typeOfMappingUsingPatternMatch[T](m: Mapping[T]) = m match { case text => println("type is String") case number => println("type is Int") case jodaTime => println("type is DateTime") case longNumber => println("type is Long") case boolean => println("type is Boolean") case _ => println("type is something else") } for(m <- testForm.mapping.mappings if m.key.nonEmpty) { print(m.key) typeOfMappingUsingPatternMatch(m) }
With the following output:
textFieldtype is String numberFieldtype is String dateFieldtype is String longFieldtype is String booleanFieldtype is String
And the following compilation warning:
[warn] /aFolder/aProject/app/controllers/IPBlocks.scala:58: patterns after a variable pattern cannot match (SLS 8.1.1) [warn] case text => println("type is String") [warn] ^ [warn] /aFolder/aProject/app/controllers/IPBlocks.scala:59: unreachable code due to variable pattern 'text' on line 58 [warn] case number => println("type is Int") [warn] ^
And the same warning as for the remaining cases.
If I change the order of affairs, then whichever case ends first, this is the one that is printed (for example, if case boolean is the first case, then the output will be is Boolean for each of the fields)
Third Attempt
Given the conclusion:
val t = text println("t == number " + (t == number)) println("t == text " + (t == text)) println("t eq number " + (t eq number)) println("t eq text " + (t eq text))
is an
t == number true t == text true t eq number false t eq text true
Using ifs and eq seems to solve the problem, so I tried:
def typeOfMappingUsingIfAndEq[T](m: Mapping[T]) = { if (m eq text) { println("type is String") } else if (m eq number) { println("type is Int") } else if (m eq jodaDate) { println("type is DateTime") } else if (m eq longNumber) { println("type is Long") } else if (m eq boolean) { println("type is Boolean") } else { println("type is something else") } } for(m <- testeForm.mapping.mappings if m.key.nonEmpty) { print(m.key) typeOfMappingUsingIfAndEq(m) }
With the next exit
textFieldtype is something else numberFieldtype is something else dateFieldtype is something else longFieldtype is something else booleanFieldtype is something else
So is there a solution to the problem? If so, what is it? Also, why is the third solution not working in hell?