Created
April 30, 2016 06:18
-
-
Save noelwelsh/b9a27832a303cc8503152fe8ce311b13 to your computer and use it in GitHub Desktop.
Attempt at extracting the names of types of the leaves of an algebraic data type
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
package underscoreio | |
package enum | |
import shapeless._ | |
import shapeless.labelled._ | |
import shapeless.syntax.singleton._ | |
// The intention of this code is to extract the names of the types at the leaves of an algebraic data type. | |
// E.g. for Color at the bottom of this file, | |
// | |
// val repr = LabelledGeneric[Color] | |
// val names = Enum.names[repr.Repr] | |
// | |
// should result in names being List("Red", "Green", "Blue") or some permutation thereof. | |
object Enum { | |
trait NameExtractor[+A] { | |
def extract: List[String] | |
} | |
object NameExtractor { | |
implicit val hnilNameExtractor: NameExtractor[HNil] = | |
new NameExtractor[HNil] { | |
def extract: List[String] = List.empty[String] | |
} | |
implicit def hconsNameExtractor[Name <: Symbol, Head, Tail <: HList]( | |
implicit | |
witness: Witness.Aux[Name], | |
tailExtractor: NameExtractor[Tail] | |
): NameExtractor[KeyTag[Name, Head] :: Tail] = | |
new NameExtractor[KeyTag[Name, Head] :: Tail] { | |
def extract: List[String] = witness.value.toString :: tailExtractor.extract | |
} | |
implicit val cnilNameExtractor: NameExtractor[CNil] = | |
new NameExtractor[CNil] { | |
def extract: List[String] = List.empty[String] | |
} | |
implicit def cconsNameExtractor[Name <: Symbol, Head, Tail <: Coproduct]( | |
implicit | |
witness: Witness.Aux[Name], | |
tailExtractor: NameExtractor[Tail] | |
): NameExtractor[KeyTag[Name, Head] :+: Tail] = | |
new NameExtractor[KeyTag[Name, Head] :+: Tail] { | |
def extract: List[String] = witness.value.toString :: tailExtractor.extract | |
} | |
} | |
def names[A](implicit extractor: NameExtractor[A]): List[String] = { | |
extractor.extract | |
} | |
} | |
sealed abstract class Color | |
final case object Red extends Color | |
final case object Green extends Color | |
final case object Blue extends Color | |
sealed abstract class Twice | |
final case object One extends Twice | |
final case object Two extends Twice | |
sealed abstract class Single | |
final case object Once extends Single | |
object Example { | |
val color = LabelledGeneric[Color] | |
val red = LabelledGeneric[Red.type] | |
val single = LabelledGeneric[Single] | |
//val names = Enum.names[single.Repr] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment