[英]F# TaskBuilder: how an exception can be raised without returning a dummy value to comply with compiler constraints?
In a F# TaskBuilder task
, I'm trying to catch an exception and re-throw it as wrapped exception:在 F# TaskBuilder
task
,我试图捕获异常并将其作为包装异常重新抛出:
open System.Threading.Tasks
open FSharp.Control.Tasks.V2
exception FakeDapperException of int
exception FakePersistenceException of string * exn
module FakeDapper =
let executeWrongQueryAsync (sql: string) =
task {
raise (FakeDapperException(0))
return 42
}
module FakePersistenceLayer =
let doSomeImportantDbRelatedStuffAsync (sql: string) =
task {
try
return! FakeDapper.executeWrongQueryAsync sql
with e ->
FakePersistenceException(sql, e) |> raise
return Unchecked.defaultof<int>
}
module Task =
let GetResult (task: Task<'T>) =
task.GetAwaiter().GetResult()
[<EntryPoint>]
let main _ =
let result =
FakePersistenceLayer.doSomeImportantDbRelatedStuffAsync "this is some pretty sql stuff"
|> Task.GetResult
0
The code above works as expected, however, when I first implemented I wanted to have something like below:上面的代码按预期工作,但是,当我第一次实现时,我想要像下面这样:
let doSomeImportantDbRelatedStuffAsync (sql: string) =
task {
try
return! FakeDapper.executeWrongQueryAsync sql
with e ->
FakePersistenceException(sql, e) |> raise
}
which could not compile:无法编译:
Program.fs(23, 17): [FS0001] Type mismatch. Expecting a 'FSharp.Control.Tasks.TaskBuilder.Step<int>' but given a 'FSharp.Control.Tasks.TaskBuilder.Step<unit>'.
The type 'int' does not match the type 'unit'
This is due to the way the task
CE works, but I am wondering if there is a way to not return a useless value (ie return Unchecked.defaultof<int>
) to stop the compiler yelling at me.这是由于
task
CE 的工作方式造成的,但我想知道是否有办法不返回无用值(即return Unchecked.defaultof<int>
)来阻止编译器对我大喊大叫。
The problem is that raise
does not know what type to infer, due to being in the task
CE.问题是
raise
不知道要推断什么类型,因为在task
CE 中。 Because the first branch try
has a return
the last branch must have one as well (this return
is where the type inference comes in)因为第一个分支
try
有一个return
所以最后一个分支也必须有一个return
值(这个return
是类型推断出现的地方)
let doSomeImportantDbRelatedStuffAsync (sql: string) =
task {
try
return! FakeDapper.executeWrongQueryAsync sql
with e ->
return FakePersistenceException(sql, e) |> raise
}
This should make the type inference happy, as raise
will infer the type of the task
CE now.这应该使类型推断变得愉快,因为
raise
将推断task
CE 的类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.