Advertisement
Guest User

Untitled

a guest
Apr 30th, 2016
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.13 KB | None | 0 0
  1. package underscoreio
  2. package enum
  3.  
  4. import shapeless._
  5. import shapeless.labelled._
  6. import shapeless.syntax.singleton._
  7.  
  8. // The intention of this code is to extract the names of the types at the leaves of an algebraic data type.
  9. // E.g. for Color at the bottom of this file,
  10. //
  11. // val repr = LabelledGeneric[Color]
  12. // val names = Enum.names[repr.Repr]
  13. //
  14. // should result in names being List("Red", "Green", "Blue") or some permutation thereof.
  15. object Enum {
  16. trait NameExtractor[+A] {
  17. def extract: List[String]
  18. }
  19.  
  20. object NameExtractor {
  21. implicit val hnilNameExtractor: NameExtractor[HNil] =
  22. new NameExtractor[HNil] {
  23. def extract: List[String] = List.empty[String]
  24. }
  25.  
  26. implicit def hconsNameExtractor[Name <: Symbol, Head, Tail <: HList](
  27. implicit
  28. witness: Witness.Aux[Name],
  29. tailExtractor: NameExtractor[Tail]
  30. ): NameExtractor[KeyTag[Name, Head] :: Tail] =
  31. new NameExtractor[KeyTag[Name, Head] :: Tail] {
  32. def extract: List[String] = witness.value.toString :: tailExtractor.extract
  33. }
  34.  
  35. implicit val cnilNameExtractor: NameExtractor[CNil] =
  36. new NameExtractor[CNil] {
  37. def extract: List[String] = List.empty[String]
  38. }
  39.  
  40. implicit def cconsNameExtractor[Name <: Symbol, Head, Tail <: Coproduct](
  41. implicit
  42. witness: Witness.Aux[Name],
  43. tailExtractor: NameExtractor[Tail]
  44. ): NameExtractor[KeyTag[Name, Head] :+: Tail] =
  45. new NameExtractor[KeyTag[Name, Head] :+: Tail] {
  46. def extract: List[String] = witness.value.toString :: tailExtractor.extract
  47. }
  48. }
  49.  
  50. def names[A](implicit extractor: NameExtractor[A]): List[String] = {
  51. extractor.extract
  52. }
  53. }
  54.  
  55. sealed abstract class Color
  56. final case object Red extends Color
  57. final case object Green extends Color
  58. final case object Blue extends Color
  59.  
  60. sealed abstract class Twice
  61. final case object One extends Twice
  62. final case object Two extends Twice
  63.  
  64. sealed abstract class Single
  65. final case object Once extends Single
  66.  
  67. object Example {
  68. val color = LabelledGeneric[Color]
  69. val red = LabelledGeneric[Red.type]
  70. val single = LabelledGeneric[Single]
  71. //val names = Enum.names[single.Repr]
  72. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement