Let a simple expression be either:
- A free variable
- A data constructor of an inductive type family, applied to 0 or more simple expressions
What would be the effect of imposing the following restriction on a programming language with inductive type families?
Given a data constructor
C
of an inductive type familyT
, withinC
's type signature,T
and(=)
(the propositional equality type constructor) may only appear fully applied to simple expressions whose free variables are bound within the type signature itself.
For example, in GHC Haskell (to avoid writing forall
s in obvious places):
{-# LANGUAGE DataKinds, GADTs, KindSignatures #-}
data Color = Red | Black
data Sign = Positive | Negative
-- Bad: Test appears applied to Color and Sign, neither
-- of which is a data constructor of an inductive type.
data Test :: * -> * where
Foo :: Integer -> Test Color
Bar :: Float -> Test Sign
-- Good: List only appears applied to free variables.
data List :: (k -> k -> *) -> k -> k -> * where
Nil :: List f a a
Cons :: f a b -> List f b c -> List f a c
-- Good: RBT appears applied to Black and Red, both of
-- which are constructors of an inductive type (Color).
data RBT :: Color -> * -> * where
Empty :: RBT Black a
R :: RBT Black a -> a -> RBT Black a -> RBT Red a
B :: RBT l a -> a -> RBT r a -> RBT Black a
Now, what I want to know is:
From the POV of language implementors, can this restriction simplify type checking? How much?
From the POV of programmers using languages like Agda, Idris, Coq, etc., are there any useful programs that type check without the restriction, that can't be refactored into equivalent programs that type check under the restriction?
From the POV of type theorists and other mathematicians using type theory as a foundational system, does the restriction prevent any useful mathematical results from being obtained internally to type theory?
Foo
to beFoo :: ∀a. Integer -> (a = Color) -> Test a
, it looks to me like your restriction is obeyed, yet you're back with the same problem. $\endgroup$