Read case class object from string in Scala (something like Haskell's "read" typeclass)
haskell, scala, serialization
Solution
dflemstr answered more towards setting up the actual `read` method- I'll answer more for the actual parsing method.
My approach has two objects that can be used in scala's pattern matching blocks. `AsInt` lets you match against strings that represent `Int`s, and `PersonString` is the actual implementation for `Person` deserialization.
object AsInt {
def unapply(s: String) = try{ Some(s.toInt) } catch {
case e: NumberFormatException => None
}
}
val PersonRegex = "Person\\((.*),(\\d+)\\)".r
object PersonString {
def unapply(str: String): Option[Person] = str match {
case PersonRegex(name, AsInt(age)) => Some(Person(name, age))
case _ => None
}
}
The magic is in the `unapply` method, which scala has syntax sugar for. So using the `PersonString` object, you could do
val person = PersonString.unapply("Person(Bob,42)")
// person will be Some(Person("Bob", 42))
or you could use a pattern matching block to do stuff with the person:
"Person(Bob,42)" match {
case PersonString(person) => println(person.name + " " + person.age)
case _ => println("Didn't get a person")
}
Problem
I'd like to read a string as an instance of a case class. For example, if the function were named "read" it would let me do the following: ``` case class Person(name: String, age: Int) val personString: String = "Person(Bob,42)" val person: Person = read(personString) ``` This is the same behavior as the read typeclass in Haskell.