Let’s say we have the following types:
sealed trait T
case object Goat extends T
case object Monk extends T
case object Tiger extends T
Now, how do you construct a collection of T such that at least one of each sub-T appears in the collection, this constraint being enforced at compile time? A collection where, contrary to this:
val s:Seq[T] = Seq(Goat)
which compiles, this:
val ts:TotalSeq[T] = TotalSeq(Goat, Goat, Tiger)
does not. I’ve used Scala above, but I would be happy to see solutions in other languages as well.
(Forgive me if my words are a bit off; I have a cold and am amusing myself today with puzzles.)
It looks like the builder pattern with generalized type constraints: http://www.tikalk.com/java/blog/type-safe-builder-scala-using-type-constraints
Something like:
Usage:
If the number of instances you want grows you can try using an HMap
Other similar approaches: phantom types: http://james-iry.blogspot.com/2010/10/phantom-types-in-haskell-and-scala.html
Another approach is to ask why you need all 3 objects. Say you want to carry an operation when the seq has all three, then you can do something like:
That way, the function onAll is not called if not all required Ts have been supplied and otherwise the violation function is called