Skip to content

Instantly share code, notes, and snippets.

@folone
Forked from eed3si9n/kind.scala
Last active February 20, 2018 22:18
Show Gist options
  • Save folone/5252361 to your computer and use it in GitHub Desktop.
Save folone/5252361 to your computer and use it in GitHub Desktop.
// Updated for Scala 2.10.0.
def kind[A: scala.reflect.runtime.universe.TypeTag](a: A): String = {
import scala.reflect.runtime.universe._
def typeKind(sig: Type): String = sig match {
case PolyType(params, resultType) =>
(params map { p =>
typeKind(p.typeSignature) match {
case "*" => "*"
case s => "(" + s + ")"
}
}).mkString(" -> ") + " -> *"
case _ => "*"
}
def typeSig(tpe: Type): Type = tpe match {
case SingleType(pre, sym) => sym.companionSymbol.typeSignature
case ExistentialType(q, TypeRef(pre, sym, args)) => sym.typeSignature
case TypeRef(pre, sym, args) => sym.typeSignature
}
val sig = typeSig(typeOf[A])
val s = typeKind(sig)
sig.typeSymbol.name + "'s kind is " + s + ". " + (s match {
case "*" =>
"This is a proper type."
case x if !(x contains "(") =>
"This is a type constructor: a 1st-order-kinded type."
case x =>
"This is a type constructor that takes type constructor(s): a higher-kinded type."
})
}
/*
scala> kind[Int]
res72: String = Int's kind is *. This is a proper type.
scala> kind[Option.type]
res73: String = Option's kind is * -> *. This is a type constructor: a 1st-order-kinded type.
scala> kind[Functor.type]
res74: String = Functor's kind is (* -> *) -> *. This is a type constructor that takes type constructor(s): a higher-kinded type.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment