Created
February 16, 2018 15:34
-
-
Save nightscape/adba260f7f7a3943417858004cd70d43 to your computer and use it in GitHub Desktop.
Experiment to use Frameless Injections to use Refined types with Spark
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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