stdlib icon indicating copy to clipboard operation
stdlib copied to clipboard

`dict.combine`

Open aslilac opened this issue 1 year ago • 7 comments
trafficstars

It'd be nice to have a Gleam version of this function: https://www.erlang.org/doc/man/maps#merge_with-3

Basically, lets you pass in a function to resolve "merge conflicts", so you could do something like...

let stuff_for_kitchen_to_make: Dict(FoodItem, Int)) =
  get_orders_from_every_table() // `List(Dict(FoodItem, Int))`
  |> list.fold(dict.new(), fn(a, b) { dict.merge(a, b, int.add) })

aslilac avatar May 08 '24 04:05 aslilac

My quick implementation looks like...


fn dict_merge_with(
  a: Dict(k, v),
  b: Dict(k, v),
  func: fn(v, v) -> v,
) -> Dict(k, v) {
  b
  |> dict.to_list()
  |> list.fold(a, fn(d, kv) {
    dict.update(d, kv.0, fn(count) {
      case count {
        option.None -> kv.1
        option.Some(v) -> func(v, kv.1)
      }
    })
  })
}

...but I have no idea if that's the way you'd like it done. Feel free to copy if you want!

aslilac avatar May 08 '24 05:05 aslilac

Sounds good, though the name proposed doesn't align with how we normally name functions. What might we call it instead?

lpil avatar May 08 '24 11:05 lpil

Not sure what you mean by “doesn’t align with”.

As some data points tho,

  • Elm calls it merge
  • Haskell calls it unionWith
  • Elixir calls it merge/3
  • Erlang (as mentioned before) calls it merge_with

Elm and Haskell also both call our current merge union.

aslilac avatar May 08 '24 16:05 aslilac

optional args would allow to just specify the combiner as an optional arg to our existing merge?

What about calling this one combine, merge_union, union_with or something?

inoas avatar May 08 '24 17:05 inoas

dict.combine(some_dicts, with: some_fn) ?

bcpeinhardt avatar May 08 '24 18:05 bcpeinhardt

yeah, I think a combine function with a with label for the "merger" function sounds pretty good :)

aslilac avatar May 08 '24 18:05 aslilac

Nice! Let's go with that

lpil avatar May 09 '24 11:05 lpil