最近我一直在阅读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