给出以下代码:
type MyType() =
static member processString (_string:string) = _string.Substring(0, 1)
static member processInt (_int:int) = _int.ToString()
static member processItems = List.map MyType.processString
static member processItems = List.map MyType.processInt
最后两行不起作用。我必须这样做:
static member processItems (_strings:string list) = _strings |> List.map MyType.processString
static member processItems (_ints:int list) = _ints |> List.map MyType.processInt
即使我这样做,第二行也会失败:
static member processItems (_strings:string list) = _strings |> List.map MyType.processString
static member processItems = List.map MyType.processInt
由于F#是带有类型推断的所有花哨裤,为什么不能弄清楚两个processItems成员函数有不同的参数签名而不必为两者明确提供参数类型他们??
答案 0 :(得分:4)
我认为问题出现是因为.NET表示级别的方法和属性之间存在差异。您的原始代码将导致两个具有相同名称的不同静态属性(不受支持)。您的中间示例定义了两个具有相同名称但不同参数类型的方法(支持这些方法)。我不确定为什么最后一个例子不起作用。请注意,我不认为这与推理有任何关系。这有效:
type MyType() =
static member processString (_string:string) = _string.Substring(0, 1)
static member processInt (_int:int) = _int.ToString()
static member processItems l = l |> List.map MyType.processString
static member processItems l = l |> List.map MyType.processInt
答案 1 :(得分:2)
对F#有更多了解的人可能会做得更好,但我认为这与成员的参数(即没有参数)的签名(作为值)有关em> 相同。这是由它们不同的返回类型,这不足以区分它们。提供显式参数可以创建不同的输入签名:
type MyType() =
static member processString (_string:string) = _string.Substring(0, 1)
static member processInt (_int:int) = _int.ToString()
static member processFloat (_float:float) = _float.ToString()
static member processItems a = a |> List.map MyType.processString
static member processItems a = a |> List.map MyType.processInt
static member processItems a = a |> List.map MyType.processFloat
如果您了解C#或C ++,请考虑如何在这些语言中创建类似于原始代码的内容。同样的问题也会得到。
答案 2 :(得分:1)
这里的问题原因不在于类型推断。在第一个示例中,使用定义两个具有相同名称但返回类型不同的属性。
type MyType() =
static member processString (_string:string) = _string.Substring(0, 1)
static member processInt (_int:int) = _int.ToString()
static member processItems = List.map MyType.processString
static member processItems = List.map MyType.processInt
第二个样本是正确的,因为您明确声明了两个方法
type MyType() =
static member processString (_string:string) = _string.Substring(0, 1)
static member processInt (_int:int) = _int.ToString()
static member processItems (_strings:string list) = _strings |> List.map MyType.processString
static member processItems (_ints:int list) = _ints |> List.map MyType.processInt
您可以通过删除类型注释来修改它:
type MyType() =
static member processString (_string:string) = _string.Substring(0, 1)
static member processInt (_int:int) = _int.ToString()
static member processItems s = s |> List.map MyType.processString
static member processItems i = i |> List.map MyType.processInt
在第三个示例中,您尝试使用相同的名称定义属性和方法(C#禁止这样做,通过IIRC,CLI规范不禁止)
type MyType() =
static member processString (_string:string) = _string.Substring(0, 1)
static member processInt (_int:int) = _int.ToString()
static member processItems (_strings:string list) = _strings |> List.map MyType.processString
static member processItems = List.map MyType.processInt