let cached_fold ~cache ~temporary ~f ~projection ~joiner ~empty =
    let folded_f = M.cached_fold ~cache ~temporary ~f ~joiner ~empty in
    function m ->
      match m with
        Top (Top_Param.Top, _) -> raise Error_Top
      | Top (Top_Param.Set s, _) ->
          let f_base base acc =
            let total_itvs = projection base in
            joiner (f base total_itvs) acc
          in
          Top_Param.O.fold f_base s empty
      | Map mm ->
          folded_f mm