diff --git a/stdpp/fin_maps.v b/stdpp/fin_maps.v
index c370d4fd49cfa938bc11838a45ee1698ed8eb512..2003c4463c8142182fbe364b673208c3bd9f48e9 100644
--- a/stdpp/fin_maps.v
+++ b/stdpp/fin_maps.v
@@ -67,14 +67,13 @@ Class FinMap K M `{FMap M, ∀ A, Lookup K A (M A), ∀ A, Empty (M A), ∀ A,
     merge f m1 m2 !! i = diag_None f (m1 !! i) (m2 !! i);
   map_fold_empty {A B} (f : K → A → B → B) (b : B) :
     map_fold f b ∅ = b;
-  map_fold_ind {A} (P : M A → Prop) :
+  map_fold_fmap_ind {A} (P : M A → Prop) :
     P ∅ →
     (∀ i x m,
       m !! i = None →
-      (∀ B (f : K → A → B → B) b,
-        map_fold f b (<[i:=x]> m) = f i x (map_fold f b m)) →
-      P m →
-      P (<[i:=x]> m)) →
+      (∀ A' B (f : K → A' → B → B) (g : A → A') b x',
+        map_fold f b (<[i:=x']> (g <$> m)) = f i x' (map_fold f b (g <$> m))) →
+      P m → P (<[i:=x]> m)) →
     ∀ m, P m;
 }.
 
@@ -305,6 +304,23 @@ Qed.
 Lemma map_empty_subseteq {A} (m : M A) : ∅ ⊆ m.
 Proof. apply map_subseteq_spec. intros k v []%lookup_empty_Some. Qed.
 
+Lemma map_fold_ind {A} (P : M A → Prop) :
+  P ∅ →
+  (∀ i x m,
+    m !! i = None →
+    (∀ B (f : K → A → B → B) b x',
+      map_fold f b (<[i:=x']> m) = f i x' (map_fold f b m)) →
+    P m → P (<[i:=x]> m)) →
+  ∀ m, P m.
+Proof.
+  intros Hemp Hins m.
+  induction m as [|i x m ? Hfold IH] using map_fold_fmap_ind; [done|].
+  apply Hins; [done| |done]. intros B f b x'.
+  assert (m = id <$> m) as ->.
+  { apply map_eq; intros j; by rewrite lookup_fmap, option_fmap_id. }
+  apply Hfold.
+Qed.
+
 Lemma map_fold_weak_ind {A B} (P : B → M A → Prop) (f : K → A → B → B) (b : B) :
   P b ∅ →
   (∀ i x m r, m !! i = None → P r m → P (f i x r) (<[i:=x]> m)) →
diff --git a/stdpp/gmap.v b/stdpp/gmap.v
index fcaebe8f0f73040dc8a8e2fe5eadc5598c58f3c4..dd093390f3057e82d7d0ea740ce0616a77cbd333 100644
--- a/stdpp/gmap.v
+++ b/stdpp/gmap.v
@@ -455,9 +455,10 @@ Local Lemma gmap_dep_fold_ind {A} {P} (Q : gmap_dep A P → Prop) :
   Q GEmpty →
   (∀ i p x mt,
     gmap_dep_lookup i mt = None →
-    (∀ j B (f : positive → A → B → B) b,
-      gmap_dep_fold f j b (gmap_dep_partial_alter (λ _, Some x) i p mt)
-      = f (Pos.reverse_go i j) x (gmap_dep_fold f j b mt)) →
+    (∀ j A' B (f : positive → A' → B → B) (g : A → A') b x',
+      gmap_dep_fold f j b
+        (gmap_dep_partial_alter (λ _, Some x') i p (gmap_dep_fmap g mt))
+      = f (Pos.reverse_go i j) x' (gmap_dep_fold f j b (gmap_dep_fmap g mt))) →
     Q mt → Q (gmap_dep_partial_alter (λ _, Some x) i p mt)) →
   ∀ mt, Q mt.
 Proof.
@@ -476,9 +477,14 @@ Proof.
       by (by destruct mt, mx as [[]|]).
     apply Hinsert.
     - by rewrite gmap_dep_lookup_GNode.
-    - intros j B f b.
-      replace (gmap_dep_partial_alter (λ _, Some x) (i~0) p (GNode mt mx GEmpty))
-        with (GNode (gmap_dep_partial_alter (λ _, Some x) i p mt) mx GEmpty)
+    - intros j A' B f g b x'.
+      replace (gmap_dep_partial_alter (λ _, Some x') (i~0) p
+          (gmap_dep_fmap g (GNode mt mx GEmpty)))
+        with (GNode (gmap_dep_partial_alter (λ _, Some x') i p (gmap_dep_fmap g mt))
+          (prod_map id g <$> mx) GEmpty)
+        by (by destruct mt, mx as [[]|]).
+      replace (gmap_dep_fmap g (GNode mt mx GEmpty))
+        with (GNode (gmap_dep_fmap g mt) (prod_map id g <$> mx) GEmpty)
         by (by destruct mt, mx as [[]|]).
       rewrite !gmap_dep_fold_GNode; simpl; auto.
     - done. }
@@ -488,9 +494,14 @@ Proof.
     by (by destruct ml, mx as [[]|], mt).
   apply Hinsert.
   - by rewrite gmap_dep_lookup_GNode.
-  - intros j B f b.
-    replace (gmap_dep_partial_alter (λ _, Some x) (i~1) p (GNode ml mx mt))
-      with (GNode ml mx (gmap_dep_partial_alter (λ _, Some x) i p mt))
+  - intros j A' B f g b x'.
+    replace (gmap_dep_partial_alter (λ _, Some x') (i~1) p
+        (gmap_dep_fmap g (GNode ml mx mt)))
+      with (GNode (gmap_dep_fmap g ml) (prod_map id g <$> mx)
+        (gmap_dep_partial_alter (λ _, Some x') i p (gmap_dep_fmap g mt)))
+      by (by destruct ml, mx as [[]|], mt).
+    replace (gmap_dep_fmap g (GNode ml mx mt))
+      with (GNode (gmap_dep_fmap g ml) (prod_map id g <$> mx) (gmap_dep_fmap g mt))
       by (by destruct ml, mx as [[]|], mt).
     rewrite !gmap_dep_fold_GNode; simpl; auto.
   - done.
@@ -514,9 +525,9 @@ Proof.
     intros i [Hk] x mt ? Hfold. destruct (fmap_Some_1 _ _ _ Hk) as (k&Hk'&->).
     assert (GMapKey Hk = gmap_key_encode k) as Hkk by (apply proof_irrel).
     rewrite Hkk in Hfold |- *. clear Hk Hkk.
-    apply (Hins k x (GMap mt)); [done|]. intros B f b.
-    trans ((match decode (encode k) with Some k => f k x | None => id end)
-      (map_fold f b (GMap mt))); [apply (Hfold 1)|].
+    apply (Hins k x (GMap mt)); [done|]. intros A' B f g b x'.
+    trans ((match decode (encode k) with Some k => f k x' | None => id end)
+      (map_fold f b (g <$> GMap mt))); [apply (Hfold 1)|].
     by rewrite Hk'.
 Qed.
 
diff --git a/stdpp/natmap.v b/stdpp/natmap.v
index 71c4283776dbe933df07e988f33d215ecf6b09ff..59c6e5d773476e8d163cb2fe9f0f40804d52a8be 100644
--- a/stdpp/natmap.v
+++ b/stdpp/natmap.v
@@ -108,6 +108,22 @@ Proof.
   rewrite natmap_lookup_singleton_raw_ne; congruence.
 Qed.
 
+Definition natmap_fmap_raw {A B} (f : A → B) : natmap_raw A → natmap_raw B :=
+  fmap (fmap (M:=option) f).
+Lemma natmap_fmap_wf {A B} (f : A → B) l :
+  natmap_wf l → natmap_wf (natmap_fmap_raw f l).
+Proof.
+  unfold natmap_fmap_raw, natmap_wf. rewrite fmap_last.
+  destruct (last l); [|done]. by apply fmap_is_Some.
+Qed.
+Lemma natmap_lookup_fmap_raw {A B} (f : A → B) i l :
+  mjoin (natmap_fmap_raw f l !! i) = f <$> mjoin (l !! i).
+Proof.
+  unfold natmap_fmap_raw. rewrite list_lookup_fmap. by destruct (l !! i).
+Qed.
+Global Instance natmap_fmap : FMap natmap := λ A B f m,
+  let (l,Hl) := m in NatMap (natmap_fmap_raw f l) (natmap_fmap_wf _ _ Hl).
+
 Definition natmap_omap_raw {A B} (f : A → option B) :
     natmap_raw A → natmap_raw B :=
   fix go l :=
@@ -167,9 +183,10 @@ Lemma natmap_fold_raw_ind {A} (P : natmap_raw A → Prop) :
   (∀ i x l,
     natmap_wf l →
     mjoin (l !! i) = None →
-    (∀ j B (f : nat → A → B → B) b,
-      natmap_fold_raw f j b (natmap_partial_alter_raw (λ _, Some x) i l)
-      = f (i + j) x (natmap_fold_raw f j b l)) →
+    (∀ j A' B (f : nat → A' → B → B) (g : A → A') b x',
+      natmap_fold_raw f j b
+        (natmap_partial_alter_raw (λ _, Some x') i (natmap_fmap_raw g l))
+      = f (i + j) x' (natmap_fold_raw f j b (natmap_fmap_raw g l))) →
     P l → P (natmap_partial_alter_raw (λ _, Some x) i l)) →
   ∀ l, natmap_wf l → P l.
 Proof.
@@ -190,9 +207,14 @@ Proof.
   apply Hinsert.
   - by apply natmap_cons_canon_wf.
   - by destruct mx, l'.
-  - intros j B f b.
-    replace (natmap_partial_alter_raw (λ _, Some x) (S i) (natmap_cons_canon mx l'))
-      with (natmap_cons_canon mx (natmap_partial_alter_raw (λ _, Some x) i l'))
+  - intros j A' B f g b x'.
+    replace (natmap_partial_alter_raw (λ _, Some x') (S i)
+        (natmap_fmap_raw g (natmap_cons_canon mx l')))
+      with (natmap_cons_canon (g <$> mx)
+        (natmap_partial_alter_raw (λ _, Some x') i (natmap_fmap_raw g l')))
+      by (by destruct i, mx, l').
+    replace (natmap_fmap_raw g (natmap_cons_canon mx l'))
+      with (natmap_cons_canon (g <$> mx) (natmap_fmap_raw g l'))
       by (by destruct i, mx, l').
     rewrite !natmap_fold_raw_cons_canon, Nat.add_succ_comm. simpl; auto.
 Qed.
@@ -200,22 +222,6 @@ Qed.
 Global Instance natmap_fold {A} : MapFold nat A (natmap A) := λ B f d m,
   let (l,_) := m in natmap_fold_raw f 0 d l.
 
-Definition natmap_fmap_raw {A B} (f : A → B) : natmap_raw A → natmap_raw B :=
-  fmap (fmap (M:=option) f).
-Lemma natmap_fmap_wf {A B} (f : A → B) l :
-  natmap_wf l → natmap_wf (natmap_fmap_raw f l).
-Proof.
-  unfold natmap_fmap_raw, natmap_wf. rewrite fmap_last.
-  destruct (last l); [|done]. by apply fmap_is_Some.
-Qed.
-Lemma natmap_lookup_fmap_raw {A B} (f : A → B) i l :
-  mjoin (natmap_fmap_raw f l !! i) = f <$> mjoin (l !! i).
-Proof.
-  unfold natmap_fmap_raw. rewrite list_lookup_fmap. by destruct (l !! i).
-Qed.
-Global Instance natmap_fmap : FMap natmap := λ A B f m,
-  let (l,Hl) := m in NatMap (natmap_fmap_raw f l) (natmap_fmap_wf _ _ Hl).
-
 Global Instance natmap_map : FinMap nat natmap.
 Proof.
   split.
@@ -248,7 +254,7 @@ Proof.
     intros i x l Hl ? Hfold H Hxl.
     replace (NatMap _ Hxl) with (<[i:=x]> (NatMap _ Hl)) by (by apply natmap_eq).
     apply Hins; [done| |done].
-    intros B f b. rewrite <-(Nat.add_0_r i) at 2. apply (Hfold 0).
+    intros A' B f g b x'. rewrite <-(Nat.add_0_r i) at 2. apply (Hfold 0).
 Qed.
 
 Fixpoint strip_Nones {A} (l : list (option A)) : list (option A) :=
diff --git a/stdpp/nmap.v b/stdpp/nmap.v
index 058bb04332a3e57cf81c318daf644d16a84050a7..0406f64d176288adddbc613809137f46ebb6b734 100644
--- a/stdpp/nmap.v
+++ b/stdpp/nmap.v
@@ -59,12 +59,12 @@ Proof.
   - intros ??? f [??] [??] [|?]; simpl; [done|]; apply (lookup_merge f).
   - done.
   - intros A P Hemp Hins [mx t].
-    induction t as [|i x t ? Hfold IH] using map_fold_ind.
+    induction t as [|i x t ? Hfold IH] using map_fold_fmap_ind.
     { destruct mx as [x|]; [|done].
       replace (NMap (Some x) ∅) with (<[0:=x]> ∅ : Nmap _) by done.
       by apply Hins. }
     apply (Hins (N.pos i) x (NMap mx t)); [done| |done].
-    intros B f b. apply Hfold.
+    intros A' B f g b. apply Hfold.
 Qed.
 
 (** * Finite sets *)
diff --git a/stdpp/pmap.v b/stdpp/pmap.v
index 8d3bb223fe7ad91f4da0af89c68db5a45776109c..9a43942b1c085aad3e142266eb147e77f1e1cc81 100644
--- a/stdpp/pmap.v
+++ b/stdpp/pmap.v
@@ -334,8 +334,9 @@ Section Pmap_fold.
     P PEmpty →
     (∀ i x mt,
       mt !! i = None →
-      (∀ j B (f : positive → A → B → B) b,
-        Pmap_fold f j b (<[i:=x]> mt) = f (Pos.reverse_go i j) x (Pmap_fold f j b mt)) →
+      (∀ j A' B (f : positive → A' → B → B) (g : A → A') b x',
+        Pmap_fold f j b (<[i:=x']> (g <$> mt))
+        = f (Pos.reverse_go i j) x' (Pmap_fold f j b (g <$> mt))) →
       P mt → P (<[i:=x]> mt)) →
     ∀ mt, P mt.
   Proof.
@@ -348,14 +349,17 @@ Section Pmap_fold.
         replace (PNode PEmpty (Some x) PEmpty)
           with (<[1:=x]> PEmpty : Pmap A) by done.
         by apply Hinsert. }
-      intros i x mt r ? Hfold.
+      intros i x mt ? Hfold ?.
       replace (PNode (<[i:=x]> mt) mx PEmpty)
         with (<[i~0:=x]> (PNode mt mx PEmpty)) by (by destruct mt, mx).
       apply Hinsert.
       - by rewrite Pmap_lookup_PNode.
-      - intros j B f b.
-        replace (<[i~0:=x]> (PNode mt mx PEmpty))
-          with (PNode (<[i:=x]> mt) mx PEmpty) by (by destruct mt, mx).
+      - intros j A' B f g b x'.
+        replace (<[i~0:=x']> (g <$> PNode mt mx PEmpty))
+          with (PNode (<[i:=x']> (g <$> mt)) (g <$> mx) PEmpty)
+          by (by destruct mt, mx).
+        replace (g <$> PNode mt mx PEmpty)
+          with (PNode (g <$> mt) (g <$> mx) PEmpty) by (by destruct mt, mx).
         rewrite !Pmap_fold_PNode; simpl; auto.
       - done. }
     intros i x mt r ? Hfold.
@@ -363,9 +367,12 @@ Section Pmap_fold.
       with (<[i~1:=x]> (PNode ml mx mt)) by (by destruct ml, mx, mt).
     apply Hinsert.
     - by rewrite Pmap_lookup_PNode.
-    - intros j B f b.
-      replace (<[i~1:=x]> (PNode ml mx mt))
-        with (PNode ml mx (<[i:=x]> mt)) by (by destruct ml, mx, mt).
+    - intros j A' B f g b x'.
+      replace (<[i~1:=x']> (g <$> PNode ml mx mt))
+        with (PNode (g <$> ml) (g <$> mx) (<[i:=x']> (g <$> mt)))
+        by (by destruct ml, mx, mt).
+      replace (g <$> PNode ml mx mt)
+        with (PNode (g <$> ml) (g <$> mx) (g <$> mt)) by (by destruct ml, mx, mt).
       rewrite !Pmap_fold_PNode; simpl; auto.
     - done.
   Qed.
diff --git a/stdpp/zmap.v b/stdpp/zmap.v
index 67dd1f6af17dc379e5e1e1724c7e94d25a7d08e5..4f0705083578dee226fb764800527d470c965281 100644
--- a/stdpp/zmap.v
+++ b/stdpp/zmap.v
@@ -63,15 +63,15 @@ Proof.
   - intros ??? f [??] [??] [|?|?]; simpl; [done| |]; apply (lookup_merge f).
   - done.
   - intros A P Hemp Hins [mx t t'].
-    induction t as [|i x t ? Hfold IH] using map_fold_ind.
-    { induction t' as [|i x t' ? Hfold IH] using map_fold_ind.
+    induction t as [|i x t ? Hfold IH] using map_fold_fmap_ind.
+    { induction t' as [|i x t' ? Hfold IH] using map_fold_fmap_ind.
       { destruct mx as [x|]; [|done].
         replace (ZMap (Some x) ∅ ∅) with (<[0:=x]> ∅ : Zmap _) by done.
         by apply Hins. }
       apply (Hins (Z.neg i) x (ZMap mx ∅ t')); [done| |done].
-      intros B f b. apply Hfold. }
+      intros A' B f g b. apply Hfold. }
     apply (Hins (Z.pos i) x (ZMap mx t t')); [done| |done].
-    intros B f b. apply Hfold.
+    intros A' B f g b. apply Hfold.
 Qed.
 
 (** * Finite sets *)