Типы — это, в парадигме λ-исчисления, гарантия конечности времени работы программы. Плата — потеря полноты по Тьюрингу; выигрыш — предсказуемость, документация и, как мы уже видели, целая логика.
Простейшая такая система — просто типизированное λ-исчисление (). Каждый терм в ней получает тип, а сами типы строятся из атомарных единственной конструкцией — стрелкой:
Три правила вывода — по одному на конструкцию терма:
Слева направо: переменная берёт свой тип из контекста ; абстракция — если в предположении тело имеет тип , то — функция типа ; аппликация — функцию можно применить только к аргументу типа , и результат получает тип .
Есть два важных свойства: первое — сильная нормализация: всякий типизируемый терм имеет НФ, и любой порядок редукции её достигает — как следствие, и нетипизируемы, а язык не полон по Тьюрингу; второе — subject reduction: тип сохраняется при редукции — «вычисление не портит тип».
А что насчёт полиморфизма? Причём по типам. В его нет: тождественная функция привязана к одному конкретному типу , и для каждого нового типа её приходится писать заново. Жирар и Рейнольдс устранили это ограничение, разрешив термам абстрагироваться не только по значениям, но и по самим типам, — получилась System F, для которой справедливо следующее:
Здесь — абстракция по типу: принимает сначала тип , затем значение этого типа и возвращает его же. Тип читается «для любого типа — функция из в »: одна и та же применима к числу, булеву значению, функции — полиморфизм стал частью самого исчисления.
Вывод типов в полной System F неразрешим, поэтому Haskell использует разрешимый фрагмент — систему Хиндли — Милнера (алгоритм W), где все типы выводятся без аннотаций; ей посвящён следующий раздел.