Предположим, я имел дело с простым текстовым протоколом, разделенным двоеточием, который выглядел примерно так:
Event:005003:information:2013 12 06 12 37 55:n3.swmml20861:1:Full client swmml20861 registered [entry=280 PID=20864 queue=0x4ca9001b]
RSET:m3node:AUTRS:1-1-24:A:0:LOADSHARE:INHIBITED:0
M3UA_IP_LINK:m3node:AUT001LKSET1:AUT001LK1:r
OPC:m3node:1-10-2(P):A7:NAT0
....
Я хотел бы десериализовать каждую строку как экземпляр класса case, но безопасным для типов способом. Моя первая попытка использует классы типов для определения методов «чтения» для каждого возможного типа, с которым я могу столкнуться, в дополнение к методу «tupled» в классе case, чтобы вернуть функцию, которая может быть применена к кортежу аргументов, что-то вроде последующий:
case class Foo(a: String, b: Integer)
trait Reader[T] {
def read(s: String): T
}
object Reader {
implicit object StringParser extends Reader[String] { def read(s: String): String = s }
implicit object IntParser extends Reader[Integer] { def read(s: String): Integer = s.toInt }
}
def create[A1, A2, Ret](fs: Seq[String], f: ((A1, A2)) => Ret)(implicit A1Reader: Reader[A1], A2Reader: Reader[A2]): Ret = {
f((A1Reader.read(fs(0)), A2Reader.read(fs(1))))
}
create(Seq("foo", "42"), Foo.tupled) // gives me a Foo("foo", 42)
Проблема, однако, в том, что мне нужно определить метод создания для каждого кортежа и арности функции, так что это означает до 22 версий создания. Кроме того, это не заботится о проверке или получении поврежденных данных.