Разрешение перегрузки с TryParse - PullRequest
7 голосов
/ 13 марта 2019

У нас есть функция, преобразующая вещи типа Int32.TryParse из использования byref в использование Option для возвращаемого значения.

let inline ToOptionFunc refFunction x =
    match refFunction x with
    | true, value  -> Some value
    | false, _     -> None

Такие вещи перестали компилироваться в .NET Core с новыми перегрузками в TryParse:

let Int32TryParse (x:string) =
     ToOptionFunc Int32.TryParse x // A unique overload for method 'TryParse' could not be determined (...)

Я перепробовал много вещей и случайно запустил его, написав так:

let Int32TryParse (x:string) =
     x |> ToOptionFunc Int32.TryParse

Я просто не понимаю, почему это компилируется, а первое - нет.

1 Ответ

11 голосов
/ 14 марта 2019

В .NET Core функция Int32.TryParse имеет некоторые дополнительные перегрузки - она ​​может анализировать либо string, либо ReadOnlySpan<char>.Оригинальный код перестал работать, потому что компилятор не знал, какую перегрузку вы хотите использовать.

  • В версии без конвейера компилятору необходимо проверить тип ToOptionFunc Int32.TryParse x.Он идет слева направо, и когда он достигает Int32.TryParse, он еще не знает о x (который имеет аннотацию типа, ограничивающую его до string), и, не зная о x, он не может знать, какой TryParse вам нужно.

  • В версии с pipe компилятору необходимо проверить тип x |> ToOptionFunc Int32.TryParse.Он идет слева направо и знает, что x равен string, поэтому он делает вывод, что функция, переданная в ToOptionFunc, должна также принимать string - и когда он проверяет Int32.TryParse, он уже может однозначно определитьперегрузка.

Итак, труба обладает очень хорошими свойствами для проверки типов!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...