dotnet / dotnet/fsharp

Help understanding type inference issue for minimal APIs - TypedResults / DynamicallyAccessedMembers

Open
#16,890 11 comments 0 reactions 0 assignees View on GitHub
Area-Diagnostics Feature Improvement
Dominant language
F#
Stars
4.3k
Forks
876
Avg merge
4d 11h
Merged PRs (30d)
131

Description

I have created an F# web project using the minimal APIs approach by running `dotnet new web -lang F#` using dotnet 8.0.

I'm trying to get this working using the `TypesResults` class, such that Open API types can be derived without me specifying them using the `Produces` method.

This works fine for the following scenario. Note the usage of the `Results` type which is required to allow the correct return types for the `indexHandler`:

```fsharp
open Microsoft.AspNetCore.Builder
open Microsoft.Extensions.Hosting
open Microsoft.AspNetCore.Http
open Microsoft.AspNetCore.Http.HttpResults
open System.Threading.Tasks

type IndexHandlerResponse = Results, ProblemHttpResult>

[]
let main args =
let builder = WebApplication.CreateBuilder(args)
let app = builder.Build()

let indexHandler (): Task =
task {
let maybe = Some "thing"

if maybe.IsSome
then return TypedResults.Ok(maybe.Value)
else return TypedResults.Problem("")
}

app.MapGet("/", Func>(indexHandler)) |> ignore
```

However, as soon as I convert this to a real-life example where the `maybe` option is wrapped in a task which gets evaluated in the body of the handler, things stop working due to "Type constraint mismatch" errors:

```fsharp
type IndexHandlerResponse = Results, ProblemHttpResult>

[]
let main args =
let builder = WebApplication.CreateBuilder(args)
let app = builder.Build()

let maybeTask = task { return Some "Hello world!"}

let indexHandler (): Task =
task {
let! maybe = maybeTask

if maybe.IsSome
then return TypedResults.Ok(maybe.Value)
else return TypedResults.Problem("")
}

app.MapGet("/", Func>(indexHandler)) |> ignore
```

Errors are as follows:

![image](https://github.com/dotnet/fsharp/assets/40315783/7f1e3672-4cd8-42aa-8962-1cf68f145a09)

![image](https://github.com/dotnet/fsharp/assets/40315783/11f3318f-e2b9-48b3-8473-3f129090323b)

Is this expected behaviour, or am I doing something wrong here? Be good to understand whether there's a known workaround for this.

In terms of a workaround this is the best I can come up with at the moment:

```fsharp
let maybeTask = task { return Some "Hello world!"}

let indexHandler (): Task =
let maybe = maybeTask.Result
task {
if maybe.IsSome
then return TypedResults.Ok(maybe.Value)
else return TypedResults.Problem("")
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.