Created
April 6, 2022 19:55
-
-
Save sagoez/e72e7839cb1d31070a6dc29d2771f72b to your computer and use it in GitHub Desktop.
This file contains hidden or 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
case class Column[A](name: String) | |
object Column { | |
def string(name: String): Column[String] = Column[String](name) | |
def int(name: String): Column[Int] = Column[Int](name) | |
} | |
// Type arguments are unchecked because they are eliminated by erasure at runtime | |
def select[A](c: Column[A]): A = c match { | |
case _: Column[String] => "String" | |
case _: Column[Int] => 42 | |
} | |
// select(Column.int("col1")) == 42 // this will throw a ClassCastException at runtime | |
/// How to fix this? | |
case class ColumnFix[A: ColumnType](name: String) { // *** | |
def columnType: ColumnType[A] = implicitly[ColumnType[A]] | |
} | |
// 1. Create a new trait to represent a column types | |
sealed trait ColumnType[A] | |
// 2. Create a companion object for each column type as implicit values | |
object ColumnType { | |
implicit case object StringColumnType extends ColumnType[String] | |
implicit case object IntColumnType extends ColumnType[Int] | |
} | |
object ColumnFix { | |
def string(name: String): ColumnFix[String] = ColumnFix[String](name) | |
def int(name: String): ColumnFix[Int] = ColumnFix[Int](name) | |
} | |
// 3. Create a function in the `ColumnFix` class that returns the type of the column and add a context bounded to the column type *** | |
// 4. Create a function to select a column with context bound to the column type. | |
// This will tell the compiler that we can call the function as long as there is an implicit instance for the column type defined for A. | |
def selectFix[A: ColumnType](c: ColumnFix[A]): A = c.columnType match { | |
case ColumnType.IntColumnType => 42 | |
case ColumnType.StringColumnType => "String" | |
} | |
selectFix(ColumnFix.int("col1")) == 42 | |
// res0: Boolean = true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment