最近我一直在閱讀vinyl
,它使用奇怪的「種類列表」有點類型。閱讀種類和乙烯基一點後,我已經得到了一定程度上的其中一個直觀的瞭解,我已經能夠破解起來這種類列表究竟如何工作?
{-# LANGUAGE DataKinds,
TypeOperators,
FlexibleInstances,
FlexibleContexts,
KindSignatures,
GADTs #-}
module Main where
-- from the data kinds page, with HCons replaced with :+:
data HList :: [*] -> * where
HNil :: HList '[]
(:+:) :: a -> HList t -> HList (a ': t)
infixr 8 :+:
instance Show (HList '[]) where
show _ = "[]"
instance (Show a, Show (HList t)) => Show (HList (a ': t)) where
show (x :+: xs) = show x ++ " : " ++ show xs
class ISum a where
isum :: Integral t => a -> t
instance ISum (HList '[]) where
isum _ = 0
instance (Integral a, ISum (HList t)) => ISum (HList (a ': t)) where
isum (x :+: xs) = fromIntegral x + isum xs
-- explicit type signatures just to check if I got them right
alist :: HList '[Integer]
alist = (3::Integer) :+: HNil
blist :: HList '[Integer,Int]
blist = (3::Integer) :+: (3::Int) :+: HNil
main :: IO()
main = do
print alist
print (isum alist :: Int)
print blist
print (isum blist :: Integer)
:i HList
產生
data HList $a where
HNil :: HList ('[] *)
(:+:) :: a -> (HList t) -> HList ((':) * a t)
-- Defined at /tmp/test.hs:10:6
instance Show (HList ('[] *)) -- Defined at /tmp/test.hs:17:10
instance (Show a, Show (HList t)) => Show (HList ((':) * a t))
-- Defined at /tmp/test.hs:19:10
instance ISum (HList ('[] *)) -- Defined at /tmp/test.hs:25:10
instance (Integral a, ISum (HList t)) => ISum (HList ((':) * a t))
-- Defined at /tmp/test.hs:29:10
*Main> :i HList
data HList $a where
HNil :: HList ('[] *)
(:+:) :: a -> (HList t) -> HList ((':) * a t)
-- Defined at /tmp/test.hs:10:6
instance Show (HList ('[] *)) -- Defined at /tmp/test.hs:17:10
instance (Show a, Show (HList t)) => Show (HList ((':) * a t))
-- Defined at /tmp/test.hs:19:10
instance ISum (HList ('[] *)) -- Defined at /tmp/test.hs:25:10
instance (Integral a, ISum (HList t)) => ISum (HList ((':) * a t))
-- Defined at /tmp/test.hs:29:10
從中我收集'[]
的糖爲'[] *
和x ': y
爲(':) * x y
。那是什麼*在那裏做?它是那種列表元素?此外,無論如何,這個名單到底是什麼?它是否構建在語言中?
非常清楚!我一直在努力徹底地獲得這個語法一段時間。 –
我真的不明白這個答案的大部分。你的例子只適用於-XPolyKinds - 我不太瞭解的另外一個擴展 - 而對我來說''t Foo''是'y - > Foo * * x y z'而不是你得到的。如果我嘗試引入foo函數 - 你沒有給出定義,所以我嘗試了'foo x y = Foo y' - GHC用「不可能發生的事情」恐慌。 – Cubic