Imagine the following scenario: The goal is to wr...
# announcements
t
Imagine the following scenario: The goal is to write a type for a name of a syntactic element. The name can either be simple or qualified. And the name can either describe a package, type or method. We would like to ensure at compile time that certain methods can only accept any kind of qualified/simple name (be it package, type or method) or any kind of type/package/method name (be it simple or qualified) or any combination thereof. I came up with the following:
Copy code
class Name<K : Name.Kind, E : Name.NamedElement>(val kind: K, val namedElement: E) {
	sealed class Kind {
		object Simple : Kind()
		object Qualified : Kind()
	}

	sealed class Element {
		object Type : Element()
		object Package : Element()
		object Method : Element()
	}
} 

fun onlyQualifiedNames(n: Name<Name.Kind.Qualified, *>)
fun onlyMethodNames(n: Name<*, Name.Element.Method>)
fun onlySimplePackageNames(n: Name<Name.Kind.Simple, Name.Element.Package>)
fun anyName(n: Name<*,*>)
What do you think? It feels way over engineered. If we were only interested in either qualified/simple or type/package/method then I would use sealed classes of course. But here we have a 2-dimensional relationship.