Now that we have injective type families, is there any remaining use case for using data families over type families?
Looking at past StackOverflow questions about d
type family T a = r | r -> a
data family D a
An injective type family T satisfies the injectivity axiom
if
T a ~ T bthena ~ b
But a data family satisfies the much stronger generativity axiom
if
D a ~ g bthenD ~ ganda ~ b
(If you like: Because the instances of D define new types that are different from any existing types.)
In fact D itself is a legitimate type in the type system, unlike a type family like T, which can only ever appear in a fully saturated application like T a. This means
D can be the argument to another type constructor, like MaybeT D. (MaybeT T is illegal.)
You can define instances for D, like instance Functor D. (You can't define instances for a type family Functor T, and it would be unusable anyway because instance selection for, e.g., map :: Functor f => (a -> b) -> f a -> f b relies on the fact that from the type f a you can determine both f and a; for this to work f cannot be allowed to vary over type families, even injective ones.)