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);};