为什么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。
答案 0 :(得分:2)
第一个错误是典型的值限制。
在f#中,函数可以是泛型函数,而不是常量函数。您可以将其解决为任何其他值限制,例如将参数移动到=
的左侧:
let f o = match true with
| true -> fseq o
| false -> failwith ""
关于第二个错误,它让你看到的混乱。由于第一个错误,代码没有编译,但intellisense告诉你另一件事。
这是正常的,特别是当代码没有编译时,intellisense会告诉你别的东西,有时它会推断出正确的类型而不是编译器,它们并不总是同步。
答案 1 :(得分:1)
问题在于您的代码的第二部分 - 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