-- different notion of recoverable than in unification, since we
-- have no metavars -- just looking to see if a constructor is failing
-- to unify with a function that may be reduced later, or if any
-- variables need to have two different constructor forms

-- The state is a mapping of name to what it has failed to unify
-- with
checkRec :: Term -> Term -> State [(Name, Term)] Bool
checkRec (P Bound x _) tm
   | isCon tm = do nmap <- get
                   case lookup x nmap of
                        Nothing -> do put ((x, tm) : nmap)
                                      return True
                        Just y' -> checkRec tm y'
 where
   isCon tm
       | (P yt _ _, _) <- unApply tm,
         conType yt = True
   isCon (Constant _) = True
   isCon _ = False

   conType (DCon _ _ _) = True
   conType (TCon _ _) = True
   conType _ = False
checkRec :: Term -> Term -> State [(Name, Term)] Bool
checkRec (P Bound x _) tm
   | isCon tm = do nmap <- get
                   case lookup x nmap of
                        Nothing -> do put ((x, tm) : nmap)
                                      return True
                        Just y' -> checkRec tm y'
 where
   isCon tm
       | (P yt _ _, _) <- unApply tm,
         conType yt = True
   isCon (Constant _) = True
   isCon _ = False

   conType (DCon _ _ _) = True
   conType (TCon _ _) = True
   conType _ = False
checkRec (P Bound x _) tm
   | isCon tm = do nmap <- get
                   case lookup x nmap of
                        Nothing -> do put ((x, tm) : nmap)
                                      return True
                        Just y' -> checkRec tm y'
 where
   isCon tm
       | (P yt _ _, _) <- unApply tm,
         conType yt = True
   isCon (Constant _) = True
   isCon _ = False

   conType (DCon _ _ _) = True
   conType (TCon _ _) = True
   conType _ = False