Saturn框架拆分模块到独立文件出现Value restriction报错如何解决
问题描述
使用Saturn和Giraffe进行F# Web开发时,将UiRoutes模块从主程序文件移动到独立文件后出现编译报错,需要明确模块放在同一文件和独立文件中的编译差异。
报错信息
Value restriction. The value 'uiRouter' has been inferred to have generic type
val uiRouter : (HttpFunc -> '_a -> HttpFuncResult) when '_a :> AspNetCore.Http.HttpContext
Either 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
差异说明与报错原因
F#的值限制规则要求顶级无参数值不能是未确定的泛型类型:
- 模块放在同一文件时,属于同一个编译单元,编译器可以通过同一文件内
appRouter的forward调用,推断出uiRouter的泛型参数'_a实际为Microsoft.AspNetCore.Http.HttpContext,不会触发报错 - 模块移动到独立文件后,每个文件是独立的编译单元,编译
UiRoutes模块时无法获取其他文件的调用信息,编译器无法确定泛型参数的具体类型,就会抛出值限制错误
解决方案
给uiRouter显式添加类型注解,锁定参数类型即可解决问题:
修改前代码:let uiRouter = htmlView carsView
修改后代码:
let (uiRouter: HttpFunc -> Microsoft.AspNetCore.Http.HttpContext -> HttpFuncResult) = htmlView carsView
内容的提问来源于stack exchange,提问作者Chilli
相关产品推荐
相关产品推荐

