Je comprends pas trop ce que tu veux faire, en particulier, que représente "Hybride" ? Si tu as "Hybride(Triangle, Triangle)" dans ta liste, tu veux le compter une seule fois, c'est bien ça ? (c'est ce que fait ton algorithme en tout cas).
type t_figure3 =
| Carre
| Triangle
| Rond
| General of int
| Hybride of t_figure3*t_figure3;;
Cela signifie que tu définis un type appelé t_figure3, et tu le spécifies en disant la forme que peuvent prendre ses éléments. Carre, Triangle et Rond sont tous les trois des figures ; si n est un entier, General(n) est une figure (intuitivement, il représente un polygone à n sommets), et si f et f' sont des figures, Hybride(f, f') est une figure (je ne sais pas trop ce qu'elle est sensée représenter).
Ta première fonction avec3 prend en argument un f de type t_figure3. La syntaxe match f with [...] permet de dire ce que ta fonction renvoie, suivant de quelle forme est f. Si c'est un triangle ou un "general(3)" (donc, un polygone à 3 sommets), tu renvoies "vrai". Si c'est un carré, un rond, ou un "général(n)" avec n différent de 3, tu renvoies "faux" (tout ceci est traité par le | _ -> false qui est un raccourcis pour dire "dans tous les autres cas, faire ci". Dans le cas de Hybride, ça renvoie "vrai" si l'une des deux figures contient un triangle / un general(3)...