F# 地图上的地图<';a、 int>;

F# 地图上的地图<';a、 int>;,f#,f#-interactive,F#,F# Interactive,我有以下类型: type MultiSet<'a when 'a: comparison> = MSet of Map<'a, int> 但它有签名: ('a -> 'b) -> Multiset<'a> -> Multiset<'b> when 'a : comparison and 'b : comparison ('a -> int) -> Multiset<'a> -> Multiset&

我有以下类型:

type MultiSet<'a when 'a: comparison> = MSet of Map<'a, int>
但它有签名:

('a -> 'b) -> Multiset<'a> -> Multiset<'b> when 'a : comparison and 'b : comparison
('a -> int) -> Multiset<'a> -> Multiset<'a> when 'a : comparison
('a->int)->当'a:比较时的多集
当我想要第一个提到的函数签名时,我的实现有什么问题

Map.Map
映射值,而不是键。还有一个很好的理由:它不能只插入映射键而不是原始键——它们可能不适合。见鬼,它们甚至可能不是所有地图的唯一。地图知道

如果你想用不同的键构建一个地图,你必须把它分解成一个序列,转换它,然后从中构建另一个
map

let map m (MSet s) =
  MSet ( Map.ofSeq <| seq { for KeyValue (key, value) in s -> m key, value } )
让映射m(MSet s)=
MSet(Map.ofSeq m键,值})
此实现具有您所需的签名

(另外,请注意,您不必进行
匹配
,您可以在参数声明中包含模式)


请注意此实现对验证新密钥不起任何作用:例如,如果它们不是唯一的,则某些计数将丢失。我将此作为练习留给读者。

这是一个很好的答案。请注意,当多个旧密钥映射到同一个新密钥时,可能也值得考虑该怎么做(计数是否应加在一起,是否应引发错误,是否应保留任意值?)这是一个好的观点。但我不想让答案过多,只是解决了眼前的问题。
let map m (MSet s) =
  MSet ( Map.ofSeq <| seq { for KeyValue (key, value) in s -> m key, value } )