【发布时间】:2015-01-26 08:39:55
【问题描述】:
我在类型推断和柯里化方面遇到问题。
我有一个这样的辅助方法:
requestToGroup :
group:'T array ->
operation:('T -> System.Threading.Tasks.Task<'B>) ->
predicate:('B -> bool) -> timeout:int -> Async<int>
基本上,这种方法允许我在多个服务中并行启动相同的操作,当所有服务都完成或超时到期时,返回有多少成功使用谓词评估它们。
考虑这些简单的定义:
type RequestA(name:string) =
member val Name=name with get,set
type ResultA(has:bool)=
member x.Has()=has
type RequestB(id:int) =
member val Id=id with get,set
type ResultB(fits:bool)=
member x.Fits()=fits
type IService =
abstract member Has: RequestA -> Task<ResultA>
abstract member Fits: RequestB -> Task<ResultB>
我可以像这样使用这个助手:
type MyClass<'T>(services:IService array) =
member x.AllHas(value:string) =
let positive = Async.RunSynchronously <| requestToGroup services (fun(s)->s.Has(RequestA(value))) (fun(r)->r.Has()) 1000
positive=services.Length
member x.AllFits(value:int, services:IService array) =
let positive = Async.RunSynchronously <| requestToGroup services (fun(s)->s.Fits(RequestB(value))) (fun(r)->r.Fits()) 1000
positive=services.Length
这一切都很好。然后我决定要咖喱 requestToGroup 函数,方法是:
type MyClass<'T>(services:IService array) =
let groupOp = requestToGroup services
member x.AllHas(value:string) =
let positive = Async.RunSynchronously <| groupOp (fun(s)->s.Has(RequestA(value))) (fun(r)->r.Has()) 1000
positive=services.Length
member x.AllFits(value:int, services:IService array) =
let positive = Async.RunSynchronously <| groupOp (fun(s)->s.Fits(RequestB(value))) (fun(r)->r.Fits()) 1000
positive=services.Length
但是现在,groupOp 推断出具体类型而不是泛型,并且在 s.Fits(RequestB(value)) 处编译失败,说这是期待 Task<RequestA> 但我提供的是 Task<RequestB>。
如何防止编译器推断具体类型?
奖励:如何使 MyClass 方法中的代码看起来更好、更清晰?
【问题讨论】:
标签: generics f# type-inference currying