Как сделать так, чтобы компилятор F # выводил мои аргументы в универсальную функцию? - PullRequest
0 голосов
/ 28 ноября 2018

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

let add_stuff<'T> x y =
   printfn "%A" (x + y)

let stuff() = 
    add_stuff 5.5 2.4
    add_stuff 3 4

Второй вызов add_stuff не компилируется.Почему это?Почему компилятор не выводит типы?

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Есть 2 проблемы с кодом:

Во-первых, универсальный тип 'T не используется ни одним из параметров.Параметры должны быть объявлены типа 'T следующим образом:

// val add_stuff: 'T -> 'T -> unit
let add_stuff<'T> (x:'T) (y:'T) =
    printfn "%A" (x + y)

Это создает новое сообщение об ошибке:

Объявленный параметр типа 'T' не может использоваться здесьпоскольку параметр типа не может быть разрешен во время компиляции

В этом случае проблема заключается в операторе +.Он использует Статически Разрешенные Параметры Типа, что означает, что ваша функция также должна использовать их, что в основном означает, что он должен быть встроенным:

// val add_stuff: ^T -> ^T -> unit
let inline add_stuff (x:^T) (y:^T) =
    printfn "%A" (x + y)

Обратите внимание на разницу в сигнатуре типа 'T является универсальным типом, он можетбыть решенным во время выполнения.^T - это SRTP, его необходимо разрешить во время компиляции, поэтому ключевое слово inline.

Если бы вы не использовали оператор +, вам не нужно было бы его вставлять.Обратите внимание на разницу между pair_stuff и add_stuff:

// val pair_stuff: 'T -> 'W -> unit
let pair_stuff (x:'T) (y:'W) =
    printfn "%A" (x , y)

// val add_stuff:  ^a -> ^b -> unit
let inline add_stuff x y =
    printfn "%A" (x + y)

let stuff() = 
    add_stuff 5.5 2.4
    add_stuff 3 4
    pair_stuff 5.5 2.4
    pair_stuff 3 4

stuff()
// 7.9
// 7
// (5.5, 2.4)
// (3, 4)
0 голосов
/ 28 ноября 2018

Вы не можете использовать Generics для этого, потому что они разрешаются во время выполнения и не будут меняться при вставке.

Вам необходимо использовать Статически разрешенные параметры типа , которые будут разрешены во время компиляции:

let inline add_stuff (x: ^X) (y: ^Y) =
    printfn "%A" (x + y)

Статически разрешенные параметры типа в первую очередь полезны в сочетании с ограничениями членов, которые являются ограничениями, которые позволяют вам указать, что аргумент типа должен иметь определенный член или элементы для использования.Невозможно создать такого рода ограничения с помощью обычного параметра универсального типа.

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