比方说,我想延长的xUnit的Assert.Throws
支持F#异步这样:泛型函数参数类型推断
Assert.AsyncThrows<InvalidOperationException>(fun() -> async { return "" })
的implentation是这样的:
module Xunit.Assert
let AsyncThrows<'TException when 'TException :> exn> asyncFunc = async {
let mutable actualException = None
try
let! r = asyncFunc()
return()
with
| :? 'TException as e -> actualException <- Some e
| _ ->()
return Assert.Throws(
(fun() ->
match actualException with
| Some ex -> raise ex
| None ->()))
}
类型的asyncFunc
是推断为unit -> Async<obj>
。这对呼叫者来说是不必要的限制;它应该是unit -> Async<'a>
。我曾尝试以下:
let AsyncThrows<'TException when 'TException :> exn> (asyncTask:unit->Async<'a>)
这并不工作,并仍编译如下Async<obj>
有一个神秘的警告(“......使代码比上表明通用的......”)。
let AsyncThrows<'TException, 'a when 'TException :> exn> (asyncTask:unit->Async<'a>)
这有效,但强制呼叫者明确地提供异步函数的返回类型,例如,
Assert.AsyncThrows<InvalidOperationException, string>(fun() -> async { return "" })
有没有办法只提供异常的类型,但不是异步函数? (注意:我的实际用例不使用异步,而是使用另一个类似的计算表达式;为了便于说明,我使用了异步)。