Map on Map<'a, int>

别来无恙 提交于 2019-12-10 21:24:48

问题


I have the following type :

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

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

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

I have tried :

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

But that it has the signature :

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

What is wrong with my implementation when I want the first mentioned function signature?


回答1:


Map.map maps values, not keys. And with good reason: it can't just go and plug the mapped keys instead of the original ones - they might not fit. Heck, they might not even be unique for all Map.map knows!

If you want to construct a map with different keys, you'll have to take it apart as a sequence, convert it, then construct another Map from it:

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

This implementation has your required signature.

(also, notice how you don't have to do match, you can include the pattern right in parameter declaration)

Beware that this implementation does nothing for validating the new keys: for example, if they turn out to be non-unique, some counts will be lost. I leave this as an exercise for the reader.



来源:https://stackoverflow.com/questions/44162927/map-on-mapa-int

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!