Набрана ракетка сильно відрізняється від Haskell. Системи типів в Lisp і Scheme, і взагалі типові системи в традиційно нетипових мовних екосистемах взагалі, мають фундаментальну мету, яку інші системи типів не мають - взаємодіяти з існуючим нетипізованим кодом . Наприклад, типізована ракетка запровадила цілі нові правила набору тексту, щоб вмістити різні ідіоми ракетки. Розглянемо цю функцію:
(define (first some-list)
(if (empty? some-list)
#f
(car some-list)))
Для порожніх списків це повертає перший елемент. Для порожніх списків це повертає помилкове значення. Це часто зустрічається в нетипізованих мовах; набрана мова використовує певний тип обгортки, Maybe
або видасть помилку в порожньому регістрі. Якщо ми хотіли додати тип до цієї функції, який тип слід використовувати? Це не так [a] -> a
(у позначенні Haskell), тому що може повернути помилкове. Це також немає [a] -> Either a Boolean
, тому що (1) він завжди повертає помилку в порожньому регістрі, а не довільне булеве значення, а (2) тип "Either" буде вбудовувати елементи в Left
false та false Right
і вимагати, щоб ви "розгорнули будь-яке", щоб дійти до фактичного елемента. Натомість значення повертає справжній союз- немає конструкторів для обгортки, він просто повертає один тип в деяких випадках, а інший - в інших випадках. У набраній ракетці це представлено конструктором типу об'єднання:
(: first (All (A) (-> (Listof A) (U A #f))))
(define (first some-list)
(if (empty? some-list)
#f
(car some-list)))
Тип (U A #f)
станів, функція може повертати або елемент списку, або false без жодного Either
екземпляра обгортки . Засіб перевірки типів може зробити висновок, що some-list
це або тип, (Pair A (Listof A))
або порожній список, і, крім того, він робить висновок, що в двох гілках оператора if відомо, що з них є випадком . Програма перевірки типів знає, що у (car some-list)
виразі список повинен мати тип, (Pair A (Listof A))
оскільки умова if це забезпечує. Це називається типізацією явищ і покликане полегшити перехід від нетипізованого коду до введеного коду.
Проблема - міграція. Там є безліч нетипізованих кодів ракетки, і набрана ракетка не може просто змусити вас відмовитися від усіх улюблених типових бібліотек і витратити місяць, додаючи типи до вашої кодової бази, якщо ви хочете її використовувати. Ця проблема застосовується кожного разу, коли додавання типів поступово до існуючої бази коду, див. TypeScript та його будь-який тип для застосування javascript цих ідей.
Система поступового типу повинна забезпечувати інструменти для роботи із загальними нетипізованими ідіомами та взаємодії з існуючим нетипізованим кодом. Використовувати його буде досить болісно, інакше див. "Чому ми більше не використовуємо Core.typed" для прикладу Clojure.