All of the following work:
{-# LANGUAGE TypeFamilies #-}
type family TF a
type instance TF Int = String
type instance TF Bool = Char
data family DF a
data inst
(Here I am only guessing, but I want to share this thought.)
Assume we can write
data family CDF a where
CDF Int = CDFInt String
CDF Bool = CDFBool Char
CDF a = CDFOther Double
Now, what is the type of the value constructors induced by this definition? I would be tempted to say:
CDFInt :: String -> CDF Int
CDFBool :: Char -> CDF Bool
CDFOther :: Double -> CDF a
... but the last one feels very wrong, since we would get
CDFOther @ Int :: Double -> CDF Int
which should be disallowed, since in a closed data family one would expect that a (non bottom) value of CDF Int
must start with the CDFInt
constructor.
Perhaps a proper type would be
CDFOther :: (a /~ Int, a /~ Bool) => Double -> CDF a
involving "inequality constraints", but this would require more typing machinery that currently available in GHC. I have no idea if type checking / inference would remain decidable with such extension.
By contrast, type families involve no value constructors, so this issue does not arise there.