I am trying to implement a Grpc.Core.Interceptors.Interceptor
in F#. Simplified, my interceptor method takes a UnaryServerMethod<'request, 'response>
and returns a 'response
. I know what I want to return when 'response
is a particular type. But I don't know how to return it within the F# type system when the return type is generic.
Here is my current code:
type ExceptionInterceptor() =
inherit Grpc.Core.Interceptors.Interceptor()
with
override _.UnaryServerHandler(request, context, continuation: UnaryServerMethod<'request, 'response>) =
task {
try
return! continuation.Invoke(request, context)
with e ->
return
if typeof<'response> = typeof<MyResponse> then
// Compiler error:
// The 'if' expression needs to have type ''a' to satisfy context type requirements.
// It currently has type 'MyResponse'.
generateFromException e // returns type MyResponse
else
raise e
}
I don't think this is going to be possible within the F#/.NET type system. The problem is that your if
test happens at run-time, but code generation is done at compile-time. You and I know that the true
branch will only be taken when 'response
is MyResponse
, but the compiler still has to generate code for that branch that works for all types, not just MyResponse
. That means that generateFromException
has to be generic for the code to compile.