F#:函数和静态成员之间的差异
请有人给我解释一下:F#:函数和静态成员之间的差异,f#,currying,F#,Currying,请有人给我解释一下: type IItem = interface end type Item = {i:int} interface IItem type Fail = static member foo (s:string) = fun (x:IItem) -> "" let foo = fun (s:string) -> fun (x:IItem) -> "" let works = {i=1} |> foo "" let fails = {i=1} |>
type IItem = interface end
type Item = {i:int} interface IItem
type Fail = static member foo (s:string) = fun (x:IItem) -> ""
let foo = fun (s:string) -> fun (x:IItem) -> ""
let works = {i=1} |> foo ""
let fails = {i=1} |> Fail.foo ""
为什么使用静态成员函数不起作用?
如果有必要的话,我将Visual Studio 2012与.net 4.5.2一起使用。这并不是静态成员和函数之间的真正区别,而是有点微妙。这是另一个复制:
type T =
static member A () (o:obj) = ()
static member B () = fun (o:obj) -> ()
T.A () 1 // ok
T.B () 1 // huh?
请注意,T.A
和T.B
的签名是不同的(这实际上在本规范第11.2.1.1节中涉及):
这是一个通常不重要的区别,但基本上它意味着在.NET表示级别上,
a
被编译成一个有两个参数的方法(即使它看起来是用F#表示的),而B
被编译成一个有一个返回F#函数的参数的方法。这种差异最终导致了你所看到的行为。老实说,更好的问题是:为什么有效?因为当你给他们一个项目时,他们都想要一个项目
(通常不做隐式转换)-我猜这就是你的答案-第一个执行隐式强制转换,而第二个不执行。顺便说一句:你可以使用fail
来处理let fails=({I=1}:>IItem)|>fail.foo”“
PS:type fail=静态成员foo(s:string)(x:IItem)=”
-我认为这是一个带有静态成员和lambda的边缘案例(您可以在签名中看到:string->(IItem->string)
vsstring->IItem->string
这从理论上看毫无意义-我确信Tomas或其他一些具有深厚规范知识的人会过来告诉我们确切原因;)我认为这可能是因为静态成员
并不总是FSharpFunc
。。。但现在我开始猜测——这是一个有趣的问题,我希望我现在有更多的时间来做一些事情research@FyodorSoikinfoo
此处按原样工作-不寻常的编写foo
静态成员工作方式不同(尽管乍一看它看起来非常相似)-我不会称之为bug,但在我看来它离它不远了(一个string->IItem->string
和一个string->(IItem->string)
之间应该没有语义上的区别——事实上,你通常会教人们这些是一样的)
type T =
class
static member A : unit -> o:obj -> unit
static member B : unit -> (obj -> unit)
end