模块位于单独文件中时土星值限制错误

Saturn Value restriction error when module is in separate file

当我将 UiRoutes 模块移动到一个单独的文件中时,编译时出现错误。这是第一次使用 Saturn 和 Giraffe,所以我不确定发生了什么?将模块放在单独的文件中有什么区别?

我得到的错误是: “值限制。值 'uiRouter' 已被推断为具有通用 type\n val uiRouter : (HttpFunc -> '_a -> HttpFuncResult) when '_a :> AspNetCore.Http.HttpContext \n要么提出论点到 'uiRouter' 显式,或者,如果您不打算让它成为通用的,请添加类型注释。"

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

解决方案:

//Changed 
let uiRouter = htmlView carsView

//to:

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

F# 分别编译每个文件。当您将 uiRouter 的定义移动到与使用它的文件不同的文件中时,F# 编译器无法再推断它具有非泛型类型。换句话说,在编译 UiRoutes.fs 时,编译器无法判断您希望 uiRouter 具有确切的类型 HttpFunc -> AspNetCore.Http.HttpContext -> HttpFuncResult。由于 F# 不允许 uiRouter 具有通用值,因此您会收到值限制错误。

这里有两种方法可以避免这种情况:

  • 确保 uiRouter 被随后在定义它的同一文件中的值的使用限制为非通用类型。
  • 提供显式类型注释以手动约束 uiRouter 的类型。

参见 similar SO question here