不清楚类型错误; ide在F#中知道类型,而编译器不知道

时间:2020-09-27 18:44:46

标签: types casting f#

我有以下代码:

override this.GetDocumentHandlers() =
    Map [
            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            (fun x ->
                use ms = new MemoryStream(x)
            ...

,我收到以下错误消息:

[FS0041] A unique overload for method 'MemoryStream' could not be determined based on type information prior to this program point. A type annotation may be needed.
Known type of argument: 'a
Candidates:
 - MemoryStream(buffer: byte []) : MemoryStream
 - MemoryStream(capacity: int) : MemoryStream

IDE告诉我它知道类型:

enter image description here

它是字节[]

此方法的用法如下:

core.GetDocumentHandlers() |> Map.iter (fun k v -> terminal.RegisterDocumentHandler(k, v))

具有:

member this.RegisterDocumentHandler (mimeType: string, handler: byte[] -> unit) =
    documentHandlers.[mimeType] <- handler

所以类型对我来说很清楚。

我想我可以避免这种问题(尽管我真的很想了解问题所在)

我做到了:

new MemoryStream(x :> byte[])

但是我得到:

[FS0059] The type 'byte []' does not have any proper subtypes and need not be used as the target of a static coercion

如果我这样做:

let doNothing bytes : byte[] = bytes
use ms = new MemoryStream(doNothing x)

然后它起作用了...

我想念什么?

1 个答案:

答案 0 :(得分:2)

首先,当编译器遇到构造函数的重载方法时,它需要能够基于它早先关于类型的信息来解决哪个重载。在您的情况下,没有类型提示会有所帮助,因此失败。您可以通过添加类型注释来解决此问题,例如在lambda函数上:

override this.GetDocumentHandlers() =
    Map [ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
          (fun (x:byte[]) ->
                use ms = new MemoryStream(x)
                .... )

您可以在其他地方放置注释-例如GetDocumentHandlers方法的返回类型。但是,这必须在过载之前完成。

第二,为什么IDE仍然显示正确的推断类型,而编译器不接受代码? F#类型检查的工作方式是从左向右进行-在IDE中,编译器通过做出“最佳猜测”来尝试从任何错误中恢复,以便继续进行并为您提供自动完成和其他提示,即使程序不完整但是,这种猜测有时可能是错误的。这对于IDE是可以接受的,但是在实际的编译器中是不可接受的。因此,在这里,您会看到一种情况,其中以IDE模式运行的编译器可以很好地猜测。

相关问题