Gõ vợt rất khác với Haskell. Các hệ thống loại trong Lisp và Scheme, và thực sự là các hệ thống trong các hệ sinh thái ngôn ngữ chưa được truyền thống nói chung, có một mục tiêu cơ bản là các hệ thống loại khác không - tương tác với mã chưa được mã hóa hiện có . Ví dụ, đánh máy vợt đã giới thiệu các quy tắc đánh máy hoàn toàn mới để phù hợp với các thành ngữ vợt khác nhau. Hãy xem xét chức năng này:
(define (first some-list)
(if (empty? some-list)
#f
(car some-list)))
Đối với danh sách không trống, điều này trả về phần tử đầu tiên. Đối với danh sách trống, điều này trả về sai. Điều này là phổ biến trong các ngôn ngữ chưa được kiểm tra; một ngôn ngữ được nhập sẽ sử dụng một số loại trình bao bọc như Maybe
hoặc ném lỗi trong trường hợp trống. Nếu chúng ta muốn thêm một loại cho chức năng này, loại nào nên được sử dụng? Nó không phải [a] -> a
(theo ký hiệu Haskell), vì nó có thể trả về false. Điều đó cũng không phải [a] -> Either a Boolean
, bởi vì (1) nó luôn trả về false trong trường hợp trống, không phải là một boolean tùy ý và (2) một loại Hoặc sẽ bao bọc các phần tử trong Left
và false Right
và yêu cầu bạn "mở khóa" hoặc để lấy phần tử thực tế. Thay vào đó, giá trị trả về một liên minh thực sự- không có hàm tạo, nó chỉ trả về một kiểu trong một số trường hợp và một kiểu khác trong các trường hợp khác. Trong Typed Vợt, điều này được thể hiện với hàm tạo kiểu kết hợp:
(: first (All (A) (-> (Listof A) (U A #f))))
(define (first some-list)
(if (empty? some-list)
#f
(car some-list)))
Kiểu này (U A #f)
cho biết hàm có thể trả về một phần tử của danh sách hoặc false mà không có bất kỳ Either
trường hợp gói nào . Trình kiểm tra loại có thể suy ra đó some-list
là loại (Pair A (Listof A))
hoặc danh sách trống, và hơn nữa nó kiểm tra rằng trong hai nhánh của câu lệnh if, nó được biết là trường hợp nào trong số đó là trường hợp . Trình kiểm tra kiểu biết rằng trong (car some-list)
biểu thức, danh sách phải có kiểu (Pair A (Listof A))
vì điều kiện if đảm bảo nó. Điều này được gọi là gõ xuất hiện và được thiết kế để dễ dàng chuyển đổi từ mã chưa được gõ sang mã đã nhập.
Vấn đề là di cư. Có rất nhiều mã vợt chưa được đánh dấu ở ngoài đó và Typed Vợt không thể buộc bạn phải từ bỏ tất cả các thư viện chưa được yêu thích và dành một tháng để thêm các loại vào cơ sở mã của bạn nếu bạn muốn sử dụng nó. Vấn đề này áp dụng bất cứ khi nào bạn thêm các loại dần dần vào một cơ sở mã hiện có, hãy xem TypeScript và bất kỳ loại nào cho ứng dụng javascript của những ý tưởng này.
Một hệ thống loại dần dần phải cung cấp các công cụ để xử lý các thành ngữ chưa được xử lý phổ biến và tương tác với mã chưa được mã hóa hiện có. Sử dụng nó sẽ khá đau nếu không, hãy xem "Tại sao chúng tôi không còn sử dụng Core.typed" để biết ví dụ về Clojure.