To se řeší buď implicitním přetypováním za běhu (v C++, C# to nesmyslně zakazuje), nebo v jazycích umožňujících mít stejnou metodu s různým návratovým typem nějakým vesměs nepěkným trikem. Ve Swiftu by bylo například
func *(m1:Matrix,m2:Matrix)->Matrix
func *(m1:Matrix,m2:Matrix)->SquareMatrix
a když se použije (m1*m2).trace, tak se automaticky vybere druhá implementace, protože nečtvercová matice stopu nemá.
Podobně, ale poněkud elegantněji, lze řešit problém dědičnosti funktorů; například diferenciální operátor bere tenzor a vrací něco jako MultidimensionalArrayWithUpperAndLowerIndices (ať žije čitelnost
), nicméně některé vrací zase tenzor. V C# a C++ pak můžu mít dva delegáty/funktory, které od sebe dědí, a pokud použiju například kovariantní nebo absolutní derivaci, lze s výsledkem pracovat jako s tenzorem bez přetypování. Obecně se takové věci ale řeší těžko, protože typový systém je záležitost doby kompilace, kdežto tady se bavíme o době běhu.