1

I'm getting a VR error on a let binding on module scope saying one of its parameters is a generic, but I don't know why that parameter is generic in the first place. This is the code:

let private asJsonResponse (responseSource: _ Task) =
    fun (next: HttpFunc) (ctx: HttpContext) ->
        task {
            let! consumption = responseSource
            return! json consumption next ctx
        }

let getVal = someFuncThatReturnsTaskOfMyType() |> asJsonResponse

The error is on the last line:

error FS0030: Value restriction. The value getVal has been inferred to have generic type val getVal: (HttpFunc -> '_a -> Task<HttpContext option>) when '_a :> HttpContext Either make the arguments to getVal explicit or, if you do not intend for it to be generic, add a type annotation.

I understand that it essentially generalizes ctx: HttpContext to something that can be cast to HttpContext. Why does this happen? And why only for this parameter and not next: HttpFunc?

HttpContext is a class and HttpFunc is a function type, is that the problem?

Timo
  • 9,269
  • 2
  • 28
  • 58
  • Are you sure this is exactly the code you're working with? Could it be that you forgot to recompile a module after making a change? – Fyodor Soikin Dec 18 '20 at 22:45
  • @FyodorSoikin I did a full rebuild before posting here to verify, the code is copy pasted from my source file (except some name changes). – Timo Dec 18 '20 at 23:43
  • Try adding type annotations all over the place and see what happens. In this case, I'm guessing a type annotation on `asJsonResponse` should do it. – Arshia001 Dec 19 '20 at 13:49

1 Answers1

0

It compiles if you either add type annotations:

let getVal: HttpFunc -> HttpContext -> Task<HttpContext option> =
    someFuncThatReturnsTaskOfMyType() |> asJsonResponse

Or add explicit parameter:

let getVal f = asJsonResponse (someFuncThatReturnsTaskOfMyType()) f

The simple answer is that type inferring mechanism of the F# compiler isn't perfect. You can read about this here :

The F# compiler tries to guess the most generalized type possible that will fit, but in some cases, the compiler feels that the code is ambiguous, and, even though it looks like it is guessing the type correctly, it needs you to be more specific

and for more specific details, here is the documentation:

MSDN Automatic Generalisation in F# have some examples of it

Typically, the value restriction error occurs either when you want a construct to be generic but the compiler has insufficient information to generalize it, or when you unintentionally omit sufficient type information in a nongeneric construct.

Valeriu Seremet
  • 558
  • 1
  • 7
  • 17