1

When I move UiRoutes module into a separate file it gives me an error when compiling. This is the first time using Saturn and Giraffe so I'm not sure what is happening? What is the difference having the module in a separate file?

The error I get is: "Value restriction. The value 'uiRouter' has been inferred to have generic type\n val uiRouter : (HttpFunc -> '_a -> HttpFuncResult) when '_a :> AspNetCore.Http.HttpContext \nEither make the arguments to 'uiRouter' explicit or, if you do not intend for it to be generic, add a type annotation."

Program.fs

open Saturn
// MongoDB.FSharp.Serializers.Register()

module ApiRoutes =

    open Giraffe

    let apiRoutes =
        router {
            //Routers in here
        }


module UiRoutes =

    open Giraffe
    open Giraffe.ViewEngine
    open DBApi

    let carsView =
        html [] [
            //Some HTML
        ]

        let uiRouter = htmlView carsView //HttpFunc -> AspNetCore.Http.HttpContext -> HttpFuncResult  
    


let appRouter =
    router {
        forward "/api" ApiRoutes.apiRoutes
        forward "" UiRoutes.uiRouter
    }

let myApp = application { use_router appRouter }
run myApp

Solution:

//Changed 
let uiRouter = htmlView carsView

//to:

let (uiRouter: HttpFunc -> Microsoft.AspNetCore.Http.HttpContext -> HttpFuncResult) = htmlView carsView
4

1 回答 1

1

F# compiles each file separately. When you move the definition of uiRouter into a different file from the one where it's used, the F# compiler can no longer infer that it has a non-generic type. In other words, when compiling UiRoutes.fs, the compiler can't tell that you want uiRouter to have the exact type HttpFunc -> AspNetCore.Http.HttpContext -> HttpFuncResult. Since F# doesn't allow uiRouter to have a generic value, you get the value restriction error.

Here are two ways to avoid this situation:

  • Ensure that uiRouter is constrained to a non-generic type by a subsequent use of the value in the same file where it is defined.
  • Provide an explicit type annotation to manually constrain the type of uiRouter.

See similar SO question here.

于 2021-08-29T14:54:01.327 回答