-- | type check datatype
tcdatatypes :: Env -> DataBind -> TC Env
tcdatatypes env (DB tc tca constrs) = do

  -- check type constructor
  let tct = mkProdType (Kind Star) tca
  tcs <- tcheck env tct
  unless (tcs == Kind Star) $ throwError "Bad type constructor arguments"

  -- check data constructors
  let du = foldl App (Var tc) (map (Var . fst) tca)
  let tduList = map (mkProdType du . constrParams) constrs
  dcts <- mapM (tcheck (reverse tca ++ ((tc, tct) : env))) tduList -- Note: reverse type parameters list (tca)
  unless (all (== Kind Star) dcts) $ throwError "Bad data constructor arguments"

  -- return environment containing type constructor and data constructors
  let dctList = map (\tdu -> foldr (\(u, k) t -> Pi u k t) tdu tca) tduList
  return ((tc, tct) : zip (map constrName constrs) dctList)
tcdatatypes :: Env -> DataBind -> TC Env
tcdatatypes env (DB tc tca constrs) = do

  -- check type constructor
  let tct = mkProdType (Kind Star) tca
  tcs <- tcheck env tct
  unless (tcs == Kind Star) $ throwError "Bad type constructor arguments"

  -- check data constructors
  let du = foldl App (Var tc) (map (Var . fst) tca)
  let tduList = map (mkProdType du . constrParams) constrs
  dcts <- mapM (tcheck (reverse tca ++ ((tc, tct) : env))) tduList -- Note: reverse type parameters list (tca)
  unless (all (== Kind Star) dcts) $ throwError "Bad data constructor arguments"

  -- return environment containing type constructor and data constructors
  let dctList = map (\tdu -> foldr (\(u, k) t -> Pi u k t) tdu tca) tduList
  return ((tc, tct) : zip (map constrName constrs) dctList)
tcdatatypes env (DB tc tca constrs) = do

  -- check type constructor
  let tct = mkProdType (Kind Star) tca
  tcs <- tcheck env tct
  unless (tcs == Kind Star) $ throwError "Bad type constructor arguments"

  -- check data constructors
  let du = foldl App (Var tc) (map (Var . fst) tca)
  let tduList = map (mkProdType du . constrParams) constrs
  dcts <- mapM (tcheck (reverse tca ++ ((tc, tct) : env))) tduList -- Note: reverse type parameters list (tca)
  unless (all (== Kind Star) dcts) $ throwError "Bad data constructor arguments"

  -- return environment containing type constructor and data constructors
  let dctList = map (\tdu -> foldr (\(u, k) t -> Pi u k t) tdu tca) tduList
  return ((tc, tct) : zip (map constrName constrs) dctList)