我有以下类型:
type MultiSet<'a when 'a: comparison> = MSet of Map<'a, int>
Run Code Online (Sandbox Code Playgroud)
我现在想要使用签名声明此类型的af map函数:
('a -> 'b) -> Multiset<'a> -> Multiset<'b> when 'a : comparison and 'b : comparison
Run Code Online (Sandbox Code Playgroud)
我试过了 :
let map m ms =
match ms with
| MSet s -> MSet ( Map.map (fun key value -> m key) s )
Run Code Online (Sandbox Code Playgroud)
但它有签名:
('a -> int) -> Multiset<'a> -> Multiset<'a> when 'a : comparison
Run Code Online (Sandbox Code Playgroud)
当我想要第一个提到的函数签名时,我的实现有什么问题?
Map.map映射值,而不是键.并且有充分的理由:它不能只是插入映射键而不是原始键 - 它们可能不适合.哎呀,他们甚至可能都不是所有人都Map.map知道的!
如果你想用不同的键构造一个地图,你必须把它作为一个序列分开,转换它,然后Map从它构造另一个:
let map m (MSet s) =
MSet ( Map.ofSeq <| seq { for KeyValue (key, value) in s -> m key, value } )
Run Code Online (Sandbox Code Playgroud)
此实现具有您所需的签名.
(另外,请注意你不必怎么做match,你可以在参数声明中包含模式)
请注意,此实现不会对验证新密钥执行任何操作:例如,如果它们变得非唯一,则会丢失一些计数.我将此作为练习留给读者.
| 归档时间: |
|
| 查看次数: |
88 次 |
| 最近记录: |