Merging two Maps


#1

Hey there,

I’ve been programming for a little while with Core_kernel and I’m trying to figure out a good way to merge two Maps together. I’m confused about why this doesn’t work:

let map_merge map1 map2 = Map.Poly.fold map1 ~init:map2 ~f:Map.Poly.add_exn

It looks like add_exn expects the map argument first, but fold will only work with something that takes it last? What’s going on here? Is there some recommended pattern?

Thanks,
Sean

PS Here is my current level-best:

    let merge_maps maps =
      List.map ~f:Map.Poly.to_alist maps
      |> List.concat |> Map.Poly.of_alist_exn

#2

Your first example can be rewritten as:

let map_merge map1 map2 =
  Map.Poly.fold map1 ~init:map2 ~f:(fun ~key ~data m ->
    Map.Poly.add_exn m ~key ~data )

But I’d have a look at the documentation for Map: https://ocaml.janestreet.com/ocaml-core/latest/doc/core_kernel/Core_kernel/Map/#val-merge


#3

Are you sure Map.Poly.add_exn is appropriate here? Do you always expect the maps to be disjoint? At the very least it’s good style to rename your merge function to map_merge_exn if you intend it to be exceptionful.


#4

Fair enough - I guess I was hoping for an easier route than the merge_skewed function (for a list of maps) with its combine parameter dealing with key overlap as (and I forgot to say this in the original post) I know that the keys will be disjoint.

And I was curious if there was an intentionality behind Core_kernel disabling the functionality that used to be present in the original OCaml standard library (where Map.add was a valid argument to Map.fold).

Yep, sorry.

Good point.