You don't even need generics for that. If you have foo(Animal)
in any OOP language then you can create a new, more concrete, function |c: Cat| foo(c)
and thus go from foo(Animal)
to foo(Cat)
(even if language doesn't support that). Like this, in C++:
extern void foo(Animal*);
using Bar = void (*)(Cat*);
Bar ptr_to_foo = [](Cat* cat) { return foo(cat);};