Skip to content

Instantly share code, notes, and snippets.

@nightscape
Created February 16, 2018 15:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nightscape/adba260f7f7a3943417858004cd70d43 to your computer and use it in GitHub Desktop.
Save nightscape/adba260f7f7a3943417858004cd70d43 to your computer and use it in GitHub Desktop.
Experiment to use Frameless Injections to use Refined types with Spark
import $ivy.{
`org.typelevel::frameless-cats:0.4.0`,
`org.typelevel::frameless-dataset:0.4.0`,
`org.typelevel::frameless-ml:0.4.0`,
`org.apache.spark::spark-core:2.2.1`,
`org.apache.spark::spark-sql:2.2.1`,
`eu.timepit::refined:0.8.7`
}
import scala.language.higherKinds
import eu.timepit.refined.api.{RefType, Validate}
import org.apache.spark.{SparkContext, SparkConf}
import org.apache.spark.sql.SQLContext
import frameless._
import eu.timepit.refined._
import eu.timepit.refined.api.Refined
import eu.timepit.refined.auto._
import eu.timepit.refined.numeric._
val conf = new SparkConf().setMaster("local[*]").setAppName("refined-spark")
val sc = new SparkContext(conf)
implicit val sqlContext = new SQLContext(sc)
/**
* Implicit support for converting a refinement type to a primitive type and reverse
* @param refType The refinement carrier type
* @param validate A [[Validate]] instance for the base type and the type-level refinement predicate.
* @tparam F The refined type
* @tparam T The base type that's being refined.
* @tparam P The type-level refinement predicate
* @return A custom encoder (Injection) for type F[T, P] <=> T (e.g., Refined[Int, Positive] <=> Int)
*/
implicit def refinedToPrimitiveInjection2[F[_, _], T, P](
implicit refType: RefType[F], validate: Validate[T, P]): Injection[F[T, P], T] =
new Injection[F[T, P], T] {
def apply(refined: F[T, P]): T = refType.unwrap(refined)
def invert(value: T): F[T, P] =
refType.refine[P](value) match {
case Left(errMsg) =>
throw new RuntimeException(s"Value $value does not satisfy refinement predicate: $errMsg")
case Right(r) => r
}
}
case class SomeId(id: Int Refined Positive)
val accountDs = TypedDataset.create(Seq(SomeId(5)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment