On dérive d'abord les monômes.

let deriver_monome {coeff=c ; degre=d} =
  if d = 0 then
    {coeff=0 ; degre=0}
  else
    {coeff=c*d ; degre=d-1}

Puis on itère la dérivation des monômes. Il faut juste faire attention à ne pas laisser traîner les monômes de coefficent nul.

let deriver p =
  let rec d_rec p = match p with
  | [] -> []
  | m::rem ->
     let m' = deriver_monome m in
     if
 m'.coeff = 0 then
       d_rec rem
     else
       m'::d_rec rem in
  d_rec p

On peut aussi utiliser l'itérateur List.fold_right, idéal pour parcourir une liste dans l'ordre et reconstruire une liste transformée dans le même ordre.

let deriver p =
  List.fold_right
    (fun m r ->
      let m' = deriver_monome m in
      if
 m'.coeff = 0 then
        r
      else
        m'::r)
    p []

Enfin une troisième solution, peut-être plus claire, mais un peu moins efficace, consiste à transformer le polynôme en la liste de ses monôes dérivés, puis à éliminer les monômes de coefficient nul :

let deriver p =
  let p0 = List.map deriver_monome p in
  let
 p' = List.filter (fun m -> m.coeff <> 0) p0 in
  p'

On utilise alors les fonctions de librairies List.map et List.filter, qui sont peut-être un peu plus faciles d'emploi.

Toutes ces complications sont en fait un peu gratuites (le but est de parler des itérateurs de listes), car seul le dernier monôme peut éventuellement être de degré zéro (et donc de dérivée nulle). On devrait donc plutôt écrire :

let deriver p =
  let rec d_rec p = match p with
  | [] | [{degre=0}] -> []
  | m::rem ->
     let m' = deriver_monome m in
     m'::d_rec rem in
  d_rec p

On note le motif-ou [] | [{degre=1}], qui regroupe les cas des polynômes de dérivée nulle. Le motif-ou permet de regrouper les clauses de filtrage dont les actions sont identiques. On aurait pu écrire:

 | [] -> []
 | [{degre=0}] -> []

mais c'est tellement moins beau.

Au passage il est intéressant de regarder ce qui se passe si on inverse les deux clauses du filtrage de deriver :

let deriver p =
  let rec d_rec p = match p with
  | m::rem ->
     let m' = deriver_monome m in
     m'::d_rec rem
  | ([]|[degre=0]) -> [] in
  d_rec p

Warning: this pattern is unused.