-functorLikeTraverse :: a -- ^ Case: does not contain variable
- -> a -- ^ Case: the variable itself
- -> a -- ^ Case: the variable itself, contravariantly
- -> (a -> a -> a) -- ^ Case: function type
- -> (Boxity -> [a] -> a) -- ^ Case: tuple type
- -> (Type -> a -> a) -- ^ Case: other tycon, variable only in last argument
- -> a -- ^ Case: other tycon, variable only in last argument
- -> (TcTyVar -> a -> a) -- ^ Case: forall type
- -> TcTyVar -- ^ Variable to look for
- -> Type -- ^ Type to process
- -> a
-functorLikeTraverse caseTrivial caseVar caseCoVar caseFun caseTuple caseTyApp caseWrongArg caseForAll var ty
- = fst (go False ty)
+data FFoldType a -- Describes how to fold over a Type in a functor like way
+ = FT { ft_triv :: a -- Does not contain variable
+ , ft_var :: a -- The variable itself
+ , ft_co_var :: a -- The variable itself, contravariantly
+ , ft_fun :: a -> a -> a -- Function type
+ , ft_tup :: Boxity -> [a] -> a -- Tuple type
+ , ft_ty_app :: Type -> a -> a -- Type app, variable only in last argument
+ , ft_bad_app :: a -- Type app, variable other than in last argument
+ , ft_forall :: TcTyVar -> a -> a -- Forall type
+ }
+
+functorLikeTraverse :: TyVar -- ^ Variable to look for
+ -> FFoldType a -- ^ How to fold
+ -> Type -- ^ Type to process
+ -> a
+functorLikeTraverse var (FT { ft_triv = caseTrivial, ft_var = caseVar
+ , ft_co_var = caseCoVar, ft_fun = caseFun
+ , ft_tup = caseTuple, ft_ty_app = caseTyApp
+ , ft_bad_app = caseWrongArg, ft_forall = caseForAll })
+ ty
+ = fst (go False ty)