Map on map <'a, int>

I have the following type:

type MultiSet<'a when 'a: comparison> = MSet of Map<'a, int>

      

and now I want to declare af map function for this type with signature:

('a -> 'b) -> Multiset<'a> -> Multiset<'b> when 'a : comparison and 'b : comparison

      

I tried:

let map m ms =
    match ms with
    | MSet s -> MSet ( Map.map (fun key value -> m key) s )

      

But it has a signature:

('a -> int) -> Multiset<'a> -> Multiset<'a> when 'a : comparison

      

What happened to my implementation when I need the first mentioned function signature?

+3


source share


1 answer


Map.map

displays values, not keys. And with good reason: it can't just go and plug in the mapped keys instead of the original ones - they might not match. Heck, they might not even be unique to everyone Map.map

knows!

If you want to build a map with different keys, you have to disassemble it as a sequence, transform it, and then build more from it Map

:

let map m (MSet s) =
  MSet ( Map.ofSeq <| seq { for KeyValue (key, value) in s -> m key, value } )

      



This implementation has the required signature.

(also note how you don't need to do match

, you can include the template in the parameter declaration)

Beware that this implementation does nothing to validate new keys: for example, if they are not unique, some calculations will be lost. I leave this as an exercise for the reader.

+5


source







All Articles