为 obj 删除 seq<'T> 的类型推断

type inference removing a seq<'T> for an obj

为什么 f 被推断为 obj -> int 而不是 seq<'T> -> int 类型?

  let fseq (o:'T seq) : int = 0                  //val fseq : o:seq<'T> -> int
  let f = match true with                        //f : obj -> int
                  | true ->  fun o -> fseq o
                  | false -> failwith ""

这会导致稍后出现如下奇怪的消息

  let a : (obj -> int ) list = []
  let a' = f::a  //error yet type inference says f : obj -> int 

ps : 问题不大,推理总是有极限的,在fsharp中很强大,但我想知道为什么这里的类型会统一为obj。

问题出在您的代码的第二部分 - a(obj -> int ) list 而它应该是 (obj seq -> int ) 因为它是 fseq 函数的类型。以下代码运行良好。

let fseq (o : 'T  seq) : int = 0             
let f = match true with                        
        | true ->  fun o -> fseq o
        | false -> failwith ""

let a : (obj seq -> int ) list = []
let a' = f::a

第一个错误是典型的值限制。

在 f# 中,函数可以是泛型,而不是常量。您可以像解决任何其他值限制一样解决它,例如将参数移动到 =:

的左侧
let f o = match true with                    
              | true  -> fseq o
              | false -> failwith ""

关于第二个错误,它混淆了您所看到的内容。由于第一个错误,代码未编译,但智能感知告诉您另一件事。

这很正常,特别是当代码未编译时,智能感知会告诉您其他信息,有时它会推断出正确的类型而不是编译器,它们并不总是同步的。