下面的类是公开的异步邮箱处理器的包装器 C#程序集的一些操作。但是,我不想要几个
Map<string,int>
实例,我需要几个不同的Map&lt;'K,'V&gt; 'K和'V变化的情况。 我希望我不需要一个仿函数(它可能在F#中不存在)。
module Flib.AsyncEvents
open System.Collections.Generic
type KVcoll = Map<string,int>
type Msg = Request of string * int option | Fetch of AsyncReplyChannel<KVcoll> | Clear
#nowarn "40"
type myAgent () = class
let dictAgent = MailboxProcessor.Start(fun inbox->
let dict = ref Map.empty
let rec loop = async {
let! msg = inbox.Receive()
match msg with
| Request (key, Some value) -> dict := Map.add key value !dict
| Request (key, None) -> dict := Map.remove key !dict
| Fetch(reply) -> reply.Reply(!dict)
| Clear -> dict := Map.empty
return! loop
}
loop)
member this.add(key, value) = dictAgent.Post (Request (key, Some value))
member this.del(key) = dictAgent.Post (Request(key, None))
member this.fetch() = dictAgent.PostAndReply((fun reply -> Fetch(reply)), timeout = 9000)
member this.lookup(key) = try 0, Map.find key (this.fetch()) // success
with | :? KeyNotFoundException -> -1, 0 // failure
member this.size() = this.fetch().Count
member this.clear() = dictAgent.Post (Clear)
member this.print() =
this.fetch() |> Map.iter (fun k v -> printfn "%s => %d" k v)
printfn "done"
end
顺便说一句,这是原型质量代码,显然不是那么好。
答案 0 :(得分:3)
我不确定我是否完全理解了这个问题,但是如果你想创建一个可以与不同类型的值一起使用的类型,你可以将该类定义为泛型:
type Msg<'K, 'V when 'K : comparison> =
| Request of 'K * 'V option
| Fetch of AsyncReplyChannel<Map<'K, 'V>>
| Clear
type MyAgent<'K, 'V when 'K : comparison> () = class
let dictAgent = MailboxProcessor.Start(fun inbox->
let dict : Map<'K, 'V> ref = ref Map.empty
let rec loop = async {
// (same as before)
}
loop)
要使其工作,您需要避免将键和类型的类型限制为特定类型的代码。在您的情况下,lookup
返回0
作为默认值,print
期待字符串。所以你可以用以下内容替换它们:
member this.lookup(key) = Map.tryFind key (this.fetch())
member this.print() =
this.fetch() |> Map.iter (fun k v -> printfn "%A => %A" k v)
printfn "done"