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 Pers
Scala does not have type classes, and in this case, you cannot even simulate the type class with a trait that is inherited from, because traits only express methods on an object, meaning that they have to be "owned" by a class, so you cannot put the definition of a "constructor that takes a string as the only argument" (which is what "read" might be called in OOP languages) in a trait.
Instead, you have to simulate type classes yourself. This is done like so (equivalent Haskell code in comments):
// class Read a where read :: String -> a
trait Read[A] { def read(s: String): A }
// instance Read Person where read = ... parser for Person ...
implicit object ReadPerson extends Read[Person] {
def read(s: String): Person = ... parser for Person ...
}
Then, when you have a method that depends on the type class, you have to specify it as an implicit context:
// readList :: Read a => [String] -> [a]
// readList ss = map read ss
def readList[A: Read] (ss: List[String]): List[A] = {
val r = implicitly[Read[A]] // Get the class instance of Read for type A
ss.map(r.read _)
}
The user would probably like a polymorphic method like this for ease of use:
object read {
def apply[A: Read](s: String): A = implicitly[Read[A]].read(s)
}
Then one can just write:
val person: Person = read[Person]("Person(Bob,42)")
I am not aware of any standard implementation(s) for this type class, in particular.
Also, a disclaimer: I don't have a Scala compiler and haven't used the language for years, so I can't guarantee that this code compiles.