typeCheckModule :: Module -> TypeCheck TCEnv
typeCheckModule = \case
  Module _ _is decls -> do
    let tcDecl d@(Decl x _ _ _) = mapReader (Map.delete x) $ typeCheckDecl d
        tDecl (Decl x args ret _) = (x, foldr TFun ret (map snd args))
        tDecls = map tDecl decls
        -- shadow existing bindings
        extend env = Map.union (Map.fromList tDecls) env
    _ <- mapReader extend (mapM tcDecl decls)
    return (extend Map.empty)
typeCheckModule :: Module -> TypeCheck TCEnv
typeCheckModule = \case
  Module _ _is decls -> do
    let tcDecl d@(Decl x _ _ _) = mapReader (Map.delete x) $ typeCheckDecl d
        tDecl (Decl x args ret _) = (x, foldr TFun ret (map snd args))
        tDecls = map tDecl decls
        -- shadow existing bindings
        extend env = Map.union (Map.fromList tDecls) env
    _ <- mapReader extend (mapM tcDecl decls)
    return (extend Map.empty)
typeCheckModule = \case
  Module _ _is decls -> do
    let tcDecl d@(Decl x _ _ _) = mapReader (Map.delete x) $ typeCheckDecl d
        tDecl (Decl x args ret _) = (x, foldr TFun ret (map snd args))
        tDecls = map tDecl decls
        -- shadow existing bindings
        extend env = Map.union (Map.fromList tDecls) env
    _ <- mapReader extend (mapM tcDecl decls)
    return (extend Map.empty)