Wpisany Rakieta bardzo różni się od Haskell. Systemy typów w Lisp i Scheme, a także systemy typów w tradycyjnie ekosystemach bez typowych języków, mają fundamentalny cel, którego nie mają inne systemy typów - współdziałanie z istniejącym nietypowym kodem . Na przykład Rakieta Typowa wprowadziła zupełnie nowe reguły pisania, aby uwzględnić różne idiomy Rakiety. Rozważ tę funkcję:
(define (first some-list)
(if (empty? some-list)
#f
(car some-list)))
W przypadku niepustych list zwraca pierwszy element. W przypadku pustych list zwraca wartość false. Jest to powszechne w nietypowych językach; język pisany użyłby jakiegoś typu opakowania, takiego jak Maybe
lub rzuciłby błąd w pustej skrzynce. Jeśli chcielibyśmy dodać typ do tej funkcji, jakiego typu należy użyć? Nie jest [a] -> a
(w notacji Haskella), ponieważ może zwrócić wartość false. Tak też nie jest [a] -> Either a Boolean
, ponieważ (1) zawsze zwraca false w pustym przypadku, nie jest to dowolna wartość logiczna i (2) każdy typ wstawia elementy Left
i fałszuje Right
i wymaga „rozpakowania jednego”, aby dostać się do rzeczywistego elementu. Zamiast tego wartość zwraca prawdziwy związek- nie ma konstruktorów zawijania, po prostu zwraca jeden typ w niektórych przypadkach, a inny typ w innych przypadkach. W Typed Racket jest to reprezentowane przez konstruktor typu unii:
(: first (All (A) (-> (Listof A) (U A #f))))
(define (first some-list)
(if (empty? some-list)
#f
(car some-list)))
Typ (U A #f)
stwierdza, że funkcja może zwrócić element listy lub wartość false bez żadnej Either
instancji zawijania . Kontroler typu może wywnioskować, że some-list
jest to albo typ, (Pair A (Listof A))
albo pusta lista, a ponadto wnioskuje, że w dwóch gałęziach instrukcji if wiadomo, która z nich jest przypadkiem . Kontroler typu wie, że w (car some-list)
wyrażeniu lista musi mieć typ, (Pair A (Listof A))
ponieważ warunek if to zapewnia. Nazywa się to typowaniem wystąpień i ma na celu ułatwienie przejścia z niepisanego kodu na kod maszynowy.
Problemem jest migracja. Istnieje mnóstwo nietypowego kodu Racket, a Typed Racket nie może zmusić cię do porzucenia wszystkich swoich ulubionych, nieopisanych bibliotek i spędzenia miesiąca na dodawaniu typów do bazy kodu, jeśli chcesz go użyć. Ten problem ma zastosowanie za każdym razem, gdy dodajesz typy stopniowo do istniejącej bazy kodu, zobacz TypeScript i jego Dowolny typ, aby zastosować javascript do tych pomysłów.
System stopniowego typu musi zapewniać narzędzia do obsługi typowych idiomów bez typu i interakcji z istniejącym nietypowym kodem. W przeciwnym razie zobaczenie „Dlaczego nie używamy już Core.typed” na przykład Clojure.