【发布时间】:2021-05-12 09:32:22
【问题描述】:
我在使用 F# 的类型推断(或者说缺乏推断)时遇到了很多无法解释的行为。
我希望下面的所有 value 函数在给定 Foo of T 的情况下都会返回正确的类型 T,但在某些情况下它会返回 obj。
type Foo<'T>(v:'T) =
member __.Value = v // 'T
static member (~~) (foo:Foo<_>) = foo.Value // Foo<'a> -> 'a
// should know the type but not always!
~~(Foo 1) // int
let value (u:Foo<_>) = u.Value // Foo<'a> -> 'a
let value (u:Foo<_>) = ~~u // Foo<obj> -> obj
let inline value (u:Foo<_>) = ~~u // Foo< ^a> -> ^a
let (~~) (foo:Foo<_>) = (Foo<_>.(~~))foo // Foo<'a> -> 'a
let value (u:Foo<_>) = ~~u // Foo<'a> -> 'a
let inline (~~) (x:^a) : ^b =
(^a : (static member (~~) : ^a -> ^b) x) // ^a -> ^b
let value (u:Foo<_>) = ~~u // Foo<obj> -> obj
let inline (~~) (x:^a) : 'b =
(^a : (static member (~~) : ^a -> 'b) x) // ^a -> 'b
let value (u:Foo<_>) = ~~u // Foo<'a> -> 'a
发生了什么事??
【问题讨论】:
-
您的问题到底是什么?我将您的代码复制粘贴到 F# 编辑器中,一切看起来都很好(除了它正在重新定义同名的值,这是不允许的)。
-
我原以为可以推断出正确的类型,但正如您从签名中看到的那样,有时会返回 obj
-
感谢您的澄清!现在有道理了!你能否在你的问题中更明确地说出来,以确保它不会被关闭?
-
确实,
let value (u:Foo<_>) = ~~u的推断正在失去泛型类型。但是为什么使用~~运算符而不是Value成员(推理适用)?您是否想隐藏Value(将其设为private)以仅使用~~访问它? -
@RomainDeneau 不,我想保存宝贵的手指动作,但最终我想了解幕后发生的事情。
标签: f# type-inference