【发布时间】:2015-06-12 05:53:24
【问题描述】:
请有人向我解释一下:
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 ""
为什么使用静态成员函数的柯里化不起作用? 如果这很重要,我正在使用带有 .net 4.5.2 的 Visual Studio 2012。
【问题讨论】:
-
说实话 - 更好的问题是:为什么
works有效 - 因为两者都想要IItem而你给他们Item(F# 通常不做隐式转换) -我想这就是你的答案 - 第一个执行隐式转换,而第二个不执行 -
顺便说一句:你得到
fail与let fails = ({i=1} :> IItem) |> Fail.foo ""工作 -
PS:
type Fail = static member foo (s:string) (x:IItem) = ""也是如此 - 我认为这是静态成员和 lambda 的边缘情况(你可以在签名中看到它:string -> (IItem -> string)vsstring -> IItem -> string这使得从理论的角度来看没有意义 - 我相信 Tomas 或其他具有深厚规范知识的人会过来告诉我们确切原因;) -
我认为这可能是因为
static member并不总是FSharpFunc...但在这里我开始猜测 - 这是一个有趣的问题,我希望我现在有更多时间做一些研究 -
@FyodorSoikin
foo在这里工作 - 这是不寻常的书面foo静态成员,它的工作方式不同(尽管乍一看它看起来非常相似) - 我不会称之为 错误,但 IMO 离它不远(string -> IItem -> string和string -> (IItem -> string)之间应该没有语义差异 - 实际上你通常会告诉人们这些是相同的)跨度>