There are businesses and people. Users can either like or post a comment about a business but the same can not happen with a person. When a user posts something about a business or likes it, that business is called the target
of that like or post:
trait TargetingRelation[TargetingType[_],TargetedType]
class Business
class Person
class Post[Target | TargetingRelation[Business,Post] ] {
def target:Target
}
class Like[Target | TargetingRelation[Business,Like] ] {
def target:Target
}
Here I'm inventing a T | P[T]
notation meaning type parameter T
such that it satisfies some property P[T]
(or T :|: P[T]
if it carries more type-appeal). Somewhere else in the code I want to have declarations like:
object canPostAboutBusiness extends TargetingRelation[Post,Business]
object canLikeBusiness extends TargetingRelation[Like,Business]
these objects are evidences actually, something like Haskell type-classes. So this would type check:
val p = new Post[Business]
val l = new Like[Business]
but not this one:
val p = new Post[Person]
val l = new Like[Person]
As far as my knowledge of Scala permits, I can't model this particular state of affairs in a satisfactory way. Now I insist that this is not sub-typing because Business is not a:
class Business extends
TargetingRelation[Post,Business] with
TargetingRelation[Like,Business]
As a matter of fact it is very desirable that Business
remains totally ignorant of the Post
. The relationship is actually outside of both Post
and Business
. Besides, I suppose the above code would not even compile to begin with since Business
is inheriting from TargetingRelation
twice. Insights are most welcome.