我有過一個類型級列表映射類型的家庭這個最小的工作示例(從singletons庫撲殺):爲什麼這段代碼不會侵犯「類型族的飽和要求」?
{-# 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
看來工作:
ghci> :set -XDataKinds
ghci> :kind! Map (TyCon1 Flip) '[Char,Int]
Map (TyCon1 Flip) '[Char,Int] :: [*]
= '[Int, Char]
的代碼解釋在帖子Defunctionalization for the win。對於「GHC不會讓一個類型變量與一個類型系列相結合」這一事實,這是一個解決方法。這被稱爲「類型族的飽和要求」。
我的疑問是:當我們「跑」:kind! Map (TyCon1 Flip) '[Char,Int]
看來,在線type instance Apply (TyCon1 f) x = f x
,f
將與我們的Flip
類型家庭匹配。爲什麼這不符合飽和要求?
我不認爲這應該工作。然而,這是完全無害的,因爲類型檢查中擴展了同義詞。 – dfeuer
我相信你真的應該爲自己的'Apply'實例提供'Flip'的defunctionalization符號。 'TyCon1'旨在應用於類型構造函數。順便說一下,這是什麼版本的GHC? – dfeuer
@dfeuer我正在使用GHC 8.0.1。顯然,這個東西在ghci中使用':kind!'時會起作用,但是如果我嘗試在腳本中添加類似Boo = Map(TyCon1 Flip)'[Char,Int]'的東西,它會給我一個編譯錯誤。 – danidiaz