2010-01-27 47 views
1

为什么不允许这样做?类型(unit - > unit)的函数是否可以在F#中静态解析类型参数?

type Foo() = 
    static member Bar() =() 

let inline bar<^a>() = //ERROR: unexpected infix operator in pattern 
    (^a : (static member Bar : unit -> unit)()) 

//Hypothetical usage: let _ = bar<Foo>() 

...但这工作正常吗?

type Foo() = 
    static member Bar() = new Foo() 

let inline bar() : ^a = 
    (^a : (static member Bar : unit -> ^a)()) 

let x : Foo = bar() 

函数是否具有静态解析类型参数以返回解析类型的实例?

回答

6

正如您所注意到的,F#将字符序列<^视为中缀运算符,因此您需要使用空格将它们分开。至于什么时候需要明确指定约束的问题,我相信规则是当你明确地给出一个函数类型参数时,你还需要指定任何必要的约束。否则,如果F#可以推断出类型参数和约束,则不需要指定它们。

所以,从你的问题这个例子正常工作:

let inline bar() :^a = 
    (^a : (static member Bar : unit -> ^a)()) 

为将这样的:

let inline bar(x : ^a) = 
    (^a : (static member Bar : unit -> unit)()) 

因为有一个泛型类型参数,但是你有没有明确的把它放在功能,和F#可以推断出所需的约束条件。

在另一方面,如果你试图修改其他例子省略明确泛型参数:

let inline bar() = 
    (^a : (static member Bar : unit -> unit)()) 

你会看到,F#不会允许这一点,因为没有办法为它图了解如何为bar()的任何给定调用实例化^a。因此,你需要明确地提供类型参数,一旦你这样做,你也必须明确提供约束。

+0

'F#将字符序列<^作为中缀运算符,因此您需要将它们与空格分开+1 – 2016-05-10 11:53:09

1

想通了。需要尖括号内的空格以及约束条件。

这工作:

type Foo() = 
    static member Bar() =() 

let inline bar< ^a when ^a : (static member Bar : unit -> unit) >() = 
    (^a : (static member Bar : unit -> unit)()) 

let _ = bar<Foo>() 

由此我们可以推测,该约束是可选的,如果该函数返回静态解析类型的实例。有谁知道这是否是规则?

相关问题