提问人:Timo 提问时间:12/19/2020 更新时间:12/26/2020 访问量:78
为什么带有显式类型注释的值在这里泛化?
Why is a value with an explicit type annotation generalized here?
问:
我在模块范围的 let 绑定上收到一个 VR 错误,说它的一个参数是泛型的,但我不知道为什么该参数首先是泛型的。代码如下:
let private asJsonResponse (responseSource: _ Task) =
fun (next: HttpFunc) (ctx: HttpContext) ->
task {
let! consumption = responseSource
return! json consumption next ctx
}
let getVal = someFuncThatReturnsTaskOfMyType() |> asJsonResponse
错误在最后一行:
错误 FS0030:值限制。当以下情况时,该值已被推断为具有泛型类型:要么将参数设置为显式,要么,如果您不希望它是泛型的,则添加类型注释。
getVal
val getVal: (HttpFunc -> '_a -> Task<HttpContext option>)
'_a :> HttpContext
getVal
我知道它本质上泛化为可以转换为 HttpContext
的东西。为什么会这样?为什么只针对这个参数而不是?ctx: HttpContext
next: HttpFunc
HttpContext
是一个类,是一个函数类型,这是问题所在吗?HttpFunc
答:
0赞
Valeriu Seremet
12/26/2020
#1
如果您添加类型注释,它就会编译:
let getVal: HttpFunc -> HttpContext -> Task<HttpContext option> =
someFuncThatReturnsTaskOfMyType() |> asJsonResponse
或者添加显式参数:
let getVal f = asJsonResponse (someFuncThatReturnsTaskOfMyType()) f
简单的答案是 F# 编译器的类型推断机制并不完美。你可以在这里读到这个 :
F# 编译器尝试猜测最通用的类型 会适合,但在某些情况下,编译器会觉得代码是 模棱两可,而且,即使它看起来像是在猜测类型 正确地,它需要你更具体
有关更具体的详细信息,请参阅以下文档:
MSDN 自动泛化 F# 中有一些示例
通常,当您需要 构造为泛型,但编译器信息不足 来概括它,或者当你无意中省略了足够的类型时 非泛型结构中的信息。
评论
asJsonResponse