Một cách để giải thích các kiểu như logic là điều kiện tồn tại cho các giá trị của kiểu trả về. Vì vậy, f :: a -> [a]
chúng tôi định lý rằng, nếu tồn tại một giá trị của loại a
, tồn tại một giá trị của loại [a]
. Việc thực hiện chức năng là bằng chứng của các đề xuất.
Đây là một lời giải thích chi tiết hơn:
Về cơ bản, các nhà xây dựng dữ liệu cho phép chúng tôi xây dựng những thứ tương tự như tổng và sản phẩm (OR và AND), nhưng chúng tôi có thể có nhiều biến thể và chúng tôi có thể đặc biệt "gắn thẻ" loại có tên để phân biệt (như tên List
).
Họ cũng cho chúng tôi xây dựng chúng một cách đệ quy: cho một đề xuất một, các đề xuất [ a ] có thể được xem như là một giải pháp cho phương trình
x ( a )⟺⊤ ∨ ( a ∧ x ( a ) )
Mọi thứ trở nên rõ ràng hơn một chút khi bạn viết định nghĩa Danh sách bằng cách sử dụng kiểu GADT, mã giả tương tự như những gì bạn thấy trong Agda:
data List : Type -> Type where
Nil : ∀ a . List a
Cons : ∀ a . a -> List a -> List a
Điều này cho chúng ta hai điều: các hàm tạo (hoặc hàm), đóng vai trò là tiên đề cho các mệnh đề List
và các tiên đề cho khớp mẫu hoặc giải mã chúng.
Nói một cách đơn giản, nó đưa ra các tiên đề sau vào logic:
- Đối với bất kỳ đề xuất một, [ a ] giữ
- Nếu một giữ, và [ a ] giữ, sau đó [ a ] giữ
- Nếu [ a ] giữ, sau đó hoặc ⊤ giữ, hoặc một ∧ [ a ] giữ
Chúng khá vô dụng khi được hiểu là logic, vì chúng ta luôn biết ⊤ giữ, giải cấu trúc ở đó không cung cấp cho chúng tôi nhiều thông tin hữu ích
Không có bộ định lượng hoặc tiện ích mở rộng loại mạnh hơn (GADT, Loại gia đình, loại phụ thuộc, v.v.), bạn có thể thấy rằng chúng tôi thực sự không thể chứng minh những điều thú vị, đó là lý do tại sao bạn thường không thấy nhiều về việc diễn giải các loại Haskell tiêu chuẩn là logic .