Functors in category theory, and also in its application to functional programming, can be seen as a kind of "structured" functions: Given two sets $A,B$, rather than just having a function $f:A\to B$, we have a functor $F$ which contains $f$, but additionally also maps morphisms on $A$ to morphisms on $B$ (i.e. maps not only $A$ to $B$ but also maps "structure on $A$" to "structure on $B$").
In the category theory of functional programming, objects $A,B$ are types and morphisms are functions $A\to B$ between types. That means functors map types $A,B$ to other types $X,Y$ and map functions $A\to B$ to functions $X\to Y$. Functors in functional programming can thus be seen as a mapping between datatypes that additionally also maps the functional structure on those data types.
My thought was: In the context of object-oriented programming, there really are more kinds of structure on datatypes than just functions between them. For example, given two types $Int$ and $Bool$, we can not only define functions $f:Int\to Bool$, but also things like $p:Int\times Bool$, or more complex datatypes like classes with private component classes.
Is there a generalization of functors to "mappings between datatypes that also preserve structure", where that doesn't need to be functorial? In particular I'm wondering whether such a concept is used in analyzing programming languages.