Tôi có ví dụ này tối thiểu làm việc (chọn lọc từ thư viện singletons) của ánh xạ một gia đình kiểu trên một danh sách loại cấp:Tại sao mã này không vi phạm "yêu cầu bão hòa của các họ loại"?
{-# language PolyKinds #-}
{-# language DataKinds #-}
{-# language TypeFamilies #-}
{-# language TypeOperators #-}
data TyFun :: * -> * -> *
data TyCon1 :: (k1 -> k2) -> (TyFun k1 k2 -> *)
type family Apply (f :: TyFun k1 k2 -> *) (x :: k1) :: k2
type instance Apply (TyCon1 f) x = f x
type family Map (f :: TyFun a b -> *) (as :: [a]) :: [b] where
Map f '[] = '[]
Map f (x ': xs) = Apply f x ': Map f xs
type family Flip t :: * where
Flip Int = Char
Flip Char = Int
Có vẻ như để làm việc:
ghci> :set -XDataKinds
ghci> :kind! Map (TyCon1 Flip) '[Char,Int]
Map (TyCon1 Flip) '[Char,Int] :: [*]
= '[Int, Char]
Mã này được giải thích trong bài đăng Defunctionalization for the win. Đó là một giải pháp cho thực tế là "GHC sẽ không cho phép một biến kiểu hợp nhất với một họ loại". Điều này được gọi là "yêu cầu bão hòa của các loại gia đình".
Nghi ngờ của tôi là: khi chúng tôi "chạy" :kind! Map (TyCon1 Flip) '[Char,Int]
có vẻ như, trong dòng type instance Apply (TyCon1 f) x = f x
, f
sẽ được khớp với gia đình loại Flip
của chúng tôi. Tại sao điều này không vi phạm yêu cầu bão hòa?
Tôi không nghĩ rằng đó là nghĩa vụ phải làm việc. Tuy nhiên, nó hoàn toàn vô hại vì các từ đồng nghĩa được mở rộng trong việc kiểm tra kiểu. – dfeuer
Tôi tin rằng bạn thực sự được yêu cầu cung cấp một biểu tượng khử chức năng cho 'Flip' với cá thể' Áp dụng' của chính nó. 'TyCon1' được thiết kế để áp dụng cho các nhà xây dựng kiểu. Nhân tiện, phiên bản GHC này là gì? – dfeuer
@dfeuer Tôi đang sử dụng GHC 8.0.1. Rõ ràng, điều này hoạt động khi sử dụng ': kind! 'Trong ghci, nhưng nếu tôi cố gắng thêm một cái gì đó như' gõ Boo = Map (TyCon1 Flip)' [Char, Int] 'vào tập lệnh, nó cho tôi một lỗi biên dịch. – danidiaz