Skip to content

Instantly share code, notes, and snippets.

@eed3si9n
Created September 3, 2012 16:40
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save eed3si9n/3610635 to your computer and use it in GitHub Desktop.
Save eed3si9n/3610635 to your computer and use it in GitHub Desktop.
calculates a type's kind
// requires Scala 2.10.0-M7
def kind[A: scala.reflect.TypeTag]: 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.
*/
@eed3si9n
Copy link
Author

eed3si9n commented Sep 3, 2012

Thanks to paulp's suggestion on twitter (http://twitter.com/extempore2/status/242672251533676544), we can now use kind[Option.type].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment