地图在地图上<'a, int>
问题描述:
我有以下类型:地图在地图上<'a, int>
type MultiSet<'a when 'a: comparison> = MSet of Map<'a, int>
,我现在想声明AF地图功能对于这种类型的带有签名:
('a -> 'b) -> Multiset<'a> -> Multiset<'b> when 'a : comparison and 'b : comparison
我曾尝试:
let map m ms =
match ms with
| MSet s -> MSet (Map.map (fun key value -> m key) s)
但它有签名:
('a -> int) -> Multiset<'a> -> Multiset<'a> when 'a : comparison
当我想要第一个提到的函数签名时,我的实现有什么问题?
答
Map.map
地图值,不是键。有充分的理由:它不能只是去插入映射的键而不是原来的键 - 它们可能不适合。哎呀,他们可能不是唯一的所有Map.map
知道!
如果你想构建具有不同的键地图,你必须把它拆开,作为一个序列,将其转换,然后从它构造另一个Map
:
let map m (MSet s) =
MSet (Map.ofSeq <| seq { for KeyValue (key, value) in s -> m key, value })
该实现你所需的签名。
(也注意到你怎么不要做match
,您可以包括右参数声明模式)
当心,这什么也不实现用于验证新密钥:例如,如果它们变成非独特的,有些计数将会丢失。我将这作为练习给读者。
这是一个很好的答案。请注意,当多个旧密钥映射到同一个新密钥(应该将计数加在一起,或者引发错误,还是保留任意值时,可能还需要考虑该怎么做)。 – kvb
这是一个很好的观点。但我不想让答案超载,只解决了眼前的问题。 –
很好的答案,非常感谢。 – Alexander