jenerik derivasyon için Shapeless kullanarak, tip güvenliği (hiçbir çalışma zamanı istisnaları, hiçbir çalışma zamanı yansıma, vb) hakkında bazı makul kısıtlamalar verilen:
import scala.util.Try
import shapeless._
trait Creator[A] { def apply(s: String): Option[A] }
object Creator {
def create[A](s: String)(implicit c: Creator[A]): Option[A] = c(s)
def instance[A](parse: String => Option[A]): Creator[A] = new Creator[A] {
def apply(s: String): Option[A] = parse(s)
}
implicit val stringCreate: Creator[String] = instance(Some(_))
implicit val intCreate: Creator[Int] = instance(s => Try(s.toInt).toOption)
implicit val doubleCreate: Creator[Double] =
instance(s => Try(s.toDouble).toOption)
implicit val hnilCreator: Creator[HNil] =
instance(s => if (s.isEmpty) Some(HNil) else None)
private[this] val NextCell = "^([^,]+)(?:,(.+))?$".r
implicit def hconsCreate[H: Creator, T <: HList: Creator]: Creator[H :: T] =
instance {
case NextCell(cell, rest) => for {
h <- create[H](cell)
t <- create[T](Option(rest).getOrElse(""))
} yield h :: t
case _ => None
}
implicit def caseClassCreate[C, R <: HList](implicit
gen: Generic.Aux[C, R],
rc: Creator[R]
): Creator[C] = instance(s => rc(s).map(gen.from))
}
değerleri Option
sarılı olduğu not temsil etmek her ne kadar (belirtilen tam olarak bu çalışma t aslında o ayrıştırma işlemi başarısız olabilir): Burada
scala> case class Person(name: String, age: Double)
defined class Person
scala> case class Book(title: String, author: String, year: Int)
defined class Book
scala> case class Country(name: String, population: Int, area: Double)
defined class Country
scala> val amy = Creator.create[Person]("Amy,54.2")
amy: Option[Person] = Some(Person(Amy,54.2))
scala> val fred = Creator.create[Person]("Fred,23")
fred: Option[Person] = Some(Person(Fred,23.0))
scala> val hamlet = Creator.create[Book]("Hamlet,Shakespeare,1600")
hamlet: Option[Book] = Some(Book(Hamlet,Shakespeare,1600))
scala> val finland = Creator.create[Country]("Finland,4500000,338424")
finland: Option[Country] = Some(Country(Finland,4500000,338424.0))
Creator
Verilen bir türü içine bir dize ayrıştırmak olabilir kanıtlar sağlayan bir tür sınıftır. String
, Int
, vb. Gibi temel türler için açık örnekler vermeliyiz, ancak vaka sınıfları için örneklerin türetilmesi için Shapeless'i kullanabiliriz (tüm üye türleri için Creator
örneğimiz olduğunu varsayarak).
Bu çok güzel Travis! Bu gösterimi biraz "Yaratıcı" [H :: T] 'yi açıklayabilir misiniz? Buradaki yazıyı nasıl okurum? – marios
Bu, "kafası H tipi ve ucu T tipi" olan HList'i okur. T, bu listede başka değerler olmadığını belirtmek için başka bir tür seviye eksileri (H2 :: T2) veya HNil'dir. –
Teşekkürler Nicolas. HList şekilsiz bir yapı mıdır? – marios