Skip to content

Instantly share code, notes, and snippets.

@noelwelsh
Created March 27, 2020 17:27
Show Gist options
  • Save noelwelsh/57f7609e80fb7b752547fdd3e13f08aa to your computer and use it in GitHub Desktop.
Save noelwelsh/57f7609e80fb7b752547fdd3e13f08aa to your computer and use it in GitHub Desktop.
import scala.compiletime._
import scala.compiletime.ops.any
final case class Col[Key, Value](data: Array[Value])
object Frame {
object Types {
type Get[F <: Tuple, Key] =
F match {
case Col[Key, v] *: cols => v
case Col[k, v] *: cols => Get[cols, Key]
case _ => Nothing
}
}
inline def get[Key, F <: Tuple](frame: F): Array[Types.Get[F, Key]] =
inline frame match {
case () => error("The frame did not have an element with the given key.")
case (c: Col[k, v]) *: cols =>
inline if(constValue[any.==[Key, k]]) c.data.asInstanceOf[Array[Types.Get[F, Key]]] else get[Key, cols.type](cols).asInstanceOf[Array[Types.Get[F, Key]]]
case _ => error("This is not a valid frame. It does not contain a tuple of Col.")
}
val frame: Col["firstName", String] *: Unit = (Col["firstName", String](Array("Dotty")) *: ())
get[Key="firstName"](frame)
// Fails with
// error] -- Error: Frame.scala:25:22 -----
// [error] 25 | get[Key="firstName"](frame)
// [error] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [error] | This is not a valid frame. It does not contain a tuple of Col.
//
// Remove the catch all pattern from get and the compilation fails with
// [error] -- Error: Frame.scala:25:22 -----
// [error] 25 | get[Key="firstName"](frame)
// [error] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [error] |cannot reduce inline match with
// [error] | scrutinee: {
// [error] | Frame.frame
// [error] |} : (Frame.frame : Col[("firstName" : String), String] *: Unit)
// [error] | patterns : case ()
// [error] | case *:.unapply[Any, Tuple](c @ _:Col[k @ _, v @ _], cols @ _):Any *: Tuple
// [error] | This location contains code that was inlined from Frame.scala:17
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment