We have an AST definition: data Term a = Lam String a | App a a | Var String deriving(Read,Show,Eq,Functor,Foldable,Traversable) And an F-Algebra for the type inference: type Wrapped m a = Enviroment -> m a type Result m = Wrapped (Type,Substitution) w :: (MonadState Int, MonadError TypeError) => Term (Result m) -> Result m w term env = ... We can get the result of running the inference using cata : infer :: (MonadState Int, MonadError TypeError) => Fix Term -> Result m infer ast = cata hm ast But now I want the result to be the original AST annotated with type information for each expression,