Definition sum_dist {A} (l : list (A * Q)) : Q :=
  List.fold_right Qplus 0 (List.map snd l).Record dist (A : Type) : Type :=
  Dist
    { dist_pmf : list (A * Q); 
      dist_law : Qeq (sum_dist dist_pmf) 1
    }.Record dist (A : Type) : Type :=
  Dist
    { dist_pmf : list (A * Q); 
      dist_law : Qeq (sum_dist dist_pmf) 1
    }.Record dist (A : Type) : Type :=
  Dist
    { dist_pmf : list (A * Q); 
      dist_law : Qeq (sum_dist dist_pmf) 1
    }.Record dist (A : Type) : Type :=
  Dist
    { dist_pmf : list (A * Q); 
      dist_law : Qeq (sum_dist dist_pmf) 1
    }.Definition mreturn_dist {A : Type} (x : A) : dist A :=
    {| dist_pmf := [(x, 1 / 1)];
       dist_law := eq_refl;
    |}.

(* Specifications: *)
Lemma refold_sum_dist: forall {A} (a : A) (q : Q) (l : list (A * Q)), sum_dist ((a, q) :: l) = q + sum_dist l.
Lemma sum_dist_app: forall {A} (l1 l2 : list (A * Q)), Qeq (sum_dist (l1 ++ l2)) (sum_dist l1 + sum_dist l2).
Lemma refold_sum_dist: forall {A} (a : A) (q : Q) (l : list (A * Q)), sum_dist ((a, q) :: l) = q + sum_dist l.
Lemma sum_dist_app: forall {A} (l1 l2 : list (A * Q)), Qeq (sum_dist (l1 ++ l2)) (sum_dist l1 + sum_dist l2).