-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHVect.hs
53 lines (37 loc) · 1.37 KB
/
HVect.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE DataKinds #-}
module HVect where
-- Teil eins: Heterogene Vektoren a.k.a. verallgemeinerte Tupel
data HVect (ts :: [*]) where
HNil :: HVect '[]
HCons :: t -> HVect ts -> HVect (t ': ts)
ex :: HVect '[Int, Char, Bool -> Bool]
ex = HCons 313 (HCons 'c' (HCons (const True) HNil))
type family Append (as :: [*]) (bs :: [*]) :: [*] where
Append '[] bs = bs
Append (a ': as) bs = a ': (Append as bs)
hVectAppend :: HVect as -> HVect bs -> HVect (Append as bs)
hVectAppend HNil bs = bs
hVectAppend (HCons a as) bs = HCons a (hVectAppend as bs)
type family HVectElim (ts :: [*]) (a :: *) :: * where
HVectElim '[] a = a
HVectElim (t ': ts) a = t -> HVectElim ts a
hVectUncurry :: HVectElim ts a -> HVect ts -> a
hVectUncurry f HNil = f
hVectUncurry f (HCons x xs) = hVectUncurry (f x) xs
data Rep (ts :: [*]) where
RNil :: Rep '[]
RCons :: Rep ts -> Rep (t ': ts)
hVectCurryExpl :: Rep ts -> (HVect ts -> a) -> HVectElim ts a
hVectCurryExpl RNil f = f HNil
hVectCurryExpl (RCons r) f = \x -> hVectCurryExpl r (f . HCons x)
class HasRep (ts :: [*]) where
hasRep :: Rep ts
instance HasRep '[] where
hasRep = RNil
instance HasRep ts => HasRep (t ': ts) where
hasRep = RCons hasRep
hVectCurry :: HasRep ts => (HVect ts -> a) -> HVectElim ts a
hVectCurry = hVectCurryExpl hasRep