2017-07-31 21 views
6

Tôi hy vọngchữ ký Kind và Gõ gia đình

type family Rep a 

type family Rep :: * -> * 

là giống nhau, nhưng có vẻ như đó là một sự khác biệt

type family Rep a 
type instance Rep Int = Char 
-- ok 

type family Rep :: * -> * 
type instance Rep Int = Char 
-- Expected kind * -> *, but got 'Int' instead 

đã tôi chỉ đơn giản vấp trên một Lỗi mở rộng Haskell, hoặc có một số điểm cho hành vi này?

+6

Điểm là loại gia đình không phải là 'chức năng mức loại'. Họ là 'gia đình các loại'. Bạn nên xem các sự tương đồng cú pháp giữa kiểu mẫu khớp giá trị và khai báo cá thể kiểu gia đình như trùng hợp ngẫu nhiên - hai ngữ nghĩa hoàn toàn khác nhau (ví dụ: thử viết hàm mức giá trị khớp với hàm tạo 'Left :: a -> Hoặc ab '). Bạn đã chứng kiến ​​một ví dụ tối thiểu về sự khác biệt. Loại gia đình thứ 2 về cơ bản chỉ là một từ đồng nghĩa kiểu, vì nó chỉ có thể có một cá thể duy nhất. The 1st là một gia đình loại thích hợp. – user2407038

+0

Tôi ước tôi có một cách đơn giản để giải thích sự khác biệt giữa 'chức năng loại mức' và 'họ của các loại', nhưng tôi thì không. Sự khác biệt xuất phát từ thực tế là gia đình loại 1 không thể áp dụng một phần (cũng không phải là thứ 2, tất nhiên, nhưng bất kỳ việc sử dụng thứ 2 là một ứng dụng bão hòa, vì phải mất 0 đối số) - nói cách khác, loại thứ nhất gia đình không có loại có thể được gán cho nó trong hệ thống kiểu Haskell. – user2407038

Trả lời

12

Vâng, có một sự khác biệt tinh tế.

đại khái, type family F a :: *->* bang rằng, nói, F Int là một đơn ánh loại constructor như [], Maybe. Này được khai thác bởi trình biên dịch, có thể gõ kiểm tra các đoạn mã sau:

type family F a :: * -> * 

-- these three examples can be removed/changed, if wished 
type instance F Int = [] 
type instance F Char = Maybe 
type instance F Bool = (,) String 

foo :: (F Int a :~: F Int b) -> (a :~: b) 
foo Refl = Refl 

Để gõ kiểm tra trên, trình biên dịch khai thác thực tế là F Int a ~ F Int b ngụ ý a ~ b, cho phép theo injectivity.

Thay vào đó, tuyên bố type family F a b :: * không đảm bảo khả năng tiêm của F Int, vì những điều sau đây trở thành hợp pháp.

type family F a b :: * 
type instance F Int a =() 
Các vấn đề liên quan