Объясните вывод типа ML программисту на C++

Как делает ML, выполняют вывод типа в следующем функциональном определении:

let add a b = a + b

Похож на это шаблоны C++, где никакая проверка типа не выполняется до точки шаблонного инстанцирования, после которого, если тип поддерживает необходимые операции, функциональные работы или иначе ошибку компиляции, брошен?

т.е. например, следующий шаблон функции

template <typename NumType>
NumType add(NumType a, NumType b) {
  return a + b;
}

будет работать на

add<int>(23, 11);

но не будет работать на

add<ostream>(cout, fout);

То, что я предполагаю, корректно, или вывод типа ML работает по-другому?

PS: Извините за мой плохой английский язык; это не мой родной язык.

5
задан Tsubasa Gomamoto 20 April 2010 в 19:27
поделиться

4 ответа

Предлагаю вам взглянуть на эту статью: Что такое Хиндли-Милнер? (и почему это круто)

Вот простейший пример, который они используют для объяснения вывода типов (это не ML, но идея та же самая):

def foo(s: String) = s.length
// note: no explicit types
def bar(x, y) = foo(x) + y

Просто взглянув на определение bar, мы легко увидим, что его тип должен быть (String, Int) => Int. Вкратце, это вывод типа. Прочтите всю статью для получения дополнительной информации и примеров.

Я не эксперт по C ++, но думаю, что шаблоны - это нечто иное, что ближе к универсальности / параметричности, а это нечто иное.

5
ответ дан 18 December 2019 в 13:12
поделиться

F # и ML в чем-то похожи в отношении вывода типов, поэтому вы можете найти

Обзор вывода типов в F #

полезным.

0
ответ дан 18 December 2019 в 13:12
поделиться

Я думаю, что попытка связать вывод типа ML практически с чем угодно в C ++ более вероятна чтобы привести к путанице, чем к пониманию. В C ++ просто нет ничего похожего на вывод типов.

Единственная часть C ++, которая не делает явной типизацию, - это шаблоны, но (по большей части) они поддерживают общие Шаблон функции C ++, подобный приведенному вами, может в равной степени применяться к неограниченному набору типов - например, в вашем коде в качестве параметра шаблона используется NumType , но он будет работать со строками. одна программа может создать экземпляр вашего add , чтобы добавить две строки в одном месте и два числа в другом месте.

ML тип i Ссылка не предназначена для общего программирования. В C или C ++ вы явно определяете тип параметра, а затем компилятор проверяет, что все, что вы пытаетесь сделать с этим параметром, разрешено этим типом.ML меняет это положение на противоположное: он смотрит на то, что вы делаете с параметром, и выясняет, каким должен быть тип , чтобы вы могли делать эти вещи. Если вы пытались делать что-то, что противоречит друг другу, он скажет вам, что не существует типа, который мог бы удовлетворить ограничениям.

Это было бы почти невозможно в C или C ++, в основном из-за всех разрешенных неявных преобразований типов. Например, если у меня есть что-то вроде a + b в ML, он может сразу сделать вывод, что a и b должны быть целыми числами, но в C или В C ++ они могут быть практически любой комбинацией целочисленных типов, типов указателей или типов с плавающей запятой (с ограничением, что они не могут оба быть указателями) или использовать определенные типы, которые перегружают оператор + (например, , std :: string ). В машинном обучении поиск типов в худшем случае может быть экспоненциальным, но почти всегда довольно быстрым. В C ++ я бы оценил, что это экспоненциально гораздо чаще, и во многих случаях, вероятно, будет недостаточно ограниченным, поэтому данная функция может иметь любую из множества различных сигнатур.

5
ответ дан 18 December 2019 в 13:12
поделиться

ML использует вывод типа Хиндли-Милнера . В этом простом случае все, что ему нужно сделать, это посмотреть на тело функции и увидеть, что она использует + с аргументами и возвращает их. Таким образом, можно сделать вывод, что аргументы должны быть типа аргументов, которые принимает + (т.е. целые числа), а функция возвращает тип, который возвращает + (также int). Таким образом, предполагаемый тип add - int -> int -> int .

Обратите внимание, что в SML (но не CAML) + также определен для других типов, кроме int, но он все равно будет выводить int, когда есть несколько возможностей (например, функция add вы определили, что нельзя использовать для добавления двух поплавков).

4
ответ дан 18 December 2019 в 13:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: