F #: Почему я должен указывать типы параметров при перегрузке функций-членов? - PullRequest
2 голосов
/ 15 августа 2010

Учитывая следующий код:

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 имеют разные сигнатуры параметров, и мне не нужно явно указывать типы параметров для обоих из них ??

Ответы [ 3 ]

4 голосов
/ 15 августа 2010

Я полагаю, что проблема возникает из-за разницы между методами и свойствами на уровне представления .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
2 голосов
/ 15 августа 2010

Кто-то, кто знает больше о F #, может, вероятно, справится с этим лучше, чем я, но я думаю, что это связано с тем фактом, что подписи аргументов (т.е. без аргументов) членов (в качестве значений)1001 * равны .Они различаются по типам возвращаемых данных, что недостаточно для их различения.Предоставление явных аргументов позволяет создавать различные входные сигнатуры:

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 ++, подумайте, как бы вы создали что-то похожее на исходный код на этих языках.Такая же проблема получится.

1 голос
/ 15 августа 2010

Причина проблемы здесь не в выводе типа. В первом примере использования определите два свойства, которые имеют одинаковые имена, но разные типы возврата.

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
...