L'énoncé donne quasiment la solution.
let rec somme p1 p2 = match p1,p2 with | [],_ -> p2 | _,[] -> p1 | ({degre=d1} as m1)::r1, ({degre=d2} as m2)::r2 -> if d1 > d2 then m1::somme r1 p2 else if d1 < d2 then m2::somme p1 r2 else (* d1 = d2 *) let c = m1.coeff + m2.coeff in if c = 0 then somme r1 r2 else {coeff=c ; degre=d1}::somme r1 r2 ;;

On peut remarquer l'emploi de la liaison as dans les motifs, pour récupérer les premiers monômes m1 et m2. Attention au parenthésage, la priorité de as est très basse. Ainsi, par exemple (p1, p2 as x) s'interprète par défaut comme ((p1, p2) as x) (et non pas comme (p1,(p2 as x))), ce qui est souvent piégeant.