La bonne convention est de choisir 1 pour le produit de la liste vide. Car d'une part la décomposition de 1 donne la liste vide, et d'autre part cette définition permet la récurrence à partir de la liste vide. Soit tout simplement :

let rec produit xs = match xs with
| [] -> 1
| x::xs -> x * produit xs