1 {- -*- coding: utf-8 -*- -}
7 FunctionalDependencies,
14 module Data.HList.Prelude
53 import Types.Data.Bool
54 import Types.Data.Num hiding ((:*:))
63 deriving (Show, Eq, Ord, Read, Typeable)
73 deriving (Show, Eq, Ord, Read, Typeable)
75 instance HList l => HList (HCons e l)
77 hCons :: HList l => e -> l -> HCons e l
84 class HExtendT e l where
86 (.&.) :: e -> l -> e :&: l
88 instance HExtendT e HNil where
89 type e :&: HNil = HCons e HNil
90 e .&. nil = hCons e nil
92 instance HList l => HExtendT e (HCons e' l) where
93 type e :&: HCons e' l = HCons e (HCons e' l)
94 e .&. HCons e' l = hCons e (hCons e' l)
100 class HAppendT l l' where
102 (.++.) :: l -> l' -> l :++: l'
104 instance HList l => HAppendT HNil l where
108 instance ( HList (l :++: l')
110 ) => HAppendT (HCons e l) l' where
111 type HCons e l :++: l' = HCons e (l :++: l')
112 (HCons e l) .++. l' = hCons e (l .++. l')
115 class ApplyT f a where
117 apply :: f -> a -> Apply f a
118 apply _ _ = undefined
121 class Apply2T f a b where
123 apply2 :: f -> a -> b -> Apply2 f a b
124 apply2 _ _ _ = undefined
129 instance ApplyT Id a where
134 data HAppendA = HAppendA
136 instance HAppendT a b => Apply2T HAppendA a b where
137 type Apply2 HAppendA a b = a :++: b
138 apply2 _ a b = a .++. b
141 class HFoldrT f v l where
143 hFoldr :: f -> v -> l -> HFoldr f v l
145 instance HFoldrT f v HNil where
146 type HFoldr f v HNil = v
149 instance ( HFoldrT f v l
150 , Apply2T f e (HFoldr f v l)
151 ) => HFoldrT f v (HCons e l) where
152 type HFoldr f v (HCons e l) = Apply2 f e (HFoldr f v l)
153 hFoldr f v (HCons e l) = apply2 f e (hFoldr f v l)
156 class HConcatT ls where
158 hConcat :: ls -> HConcat ls
160 instance HFoldrT HAppendA HNil ls => HConcatT ls where
161 type HConcat ls = HFoldr HAppendA HNil ls
162 hConcat ls = hFoldr HAppendA hNil ls
165 class HMapT f l where
167 hMap :: f -> l -> HMap f l
169 instance HMapT f HNil where
170 type HMap f HNil = HNil
173 instance ( ApplyT f x
176 ) => HMapT f (HCons x xs) where
177 type HMap f (HCons x xs) = HCons (Apply f x) (HMap f xs)
178 hMap f (HCons x xs) = hCons (apply f x) (hMap f xs)
182 type instance HAll f HNil = True
183 type instance HAll f (HCons x xs) = If (Apply f x) (HAll f xs) False
186 type family HLength l
187 type instance HLength HNil = D0
188 type instance HLength (HCons e l) = Succ (HLength l)
193 -- HOccursMany (zero or more)
194 class HOccursMany e l where
195 hOccursMany :: l -> [e]
197 instance HOccursMany e HNil where
203 => HOccursMany e (HCons e l)
205 hOccursMany (HCons e l) = e : hOccursMany l
210 => HOccursMany e (HCons e' l)
212 hOccursMany (HCons _ l) = hOccursMany l
214 -- HOccursMany1 (one or more)
215 class HOccursMany1 e l where
216 hOccursMany1 :: l -> [e]
218 instance Fail (TypeNotFound e) => HOccursMany1 e HNil where
219 hOccursMany1 _ = undefined
224 => HOccursMany1 e (HCons e l)
226 hOccursMany1 (HCons e l) = e : hOccursMany l
231 => HOccursMany1 e (HCons e' l)
233 hOccursMany1 (HCons _ l) = hOccursMany1 l
235 -- HOccursOpt (zero or one)
236 class HOccursOpt e l where
237 hOccursOpt :: l -> Maybe e
239 instance HOccursOpt e HNil where
240 hOccursOpt _ = Nothing
242 instance HOccursNot e l => HOccursOpt e (HCons e l) where
243 hOccursOpt (HCons e _) = Just e
245 instance HOccursOpt e l => HOccursOpt e (HCons e' l) where
246 hOccursOpt (HCons _ l) = hOccursOpt l
249 class HOccurs e l where
254 instance Fail (TypeNotFound e) => HOccurs e HNil
261 => HOccurs e (HCons e l)
263 hOccurs (HCons e _) = e
268 => HOccurs e (HCons e' l)
270 hOccurs (HCons _ l) = hOccurs l
275 instance HOccursNot e HNil
276 instance Fail (TypeFound e) => HOccursNot e (HCons e l)
277 instance HOccursNot e l => HOccursNot e (HCons e' l)
280 class HNoDuplicates l
281 instance HNoDuplicates HNil
282 instance HOccursNot e l => HNoDuplicates (HCons e l)
286 "Strongly Typed Heterogeneous Collections"
291 ==========================
292 9 By chance or by design?
294 We will now discuss the issues surrounding the definition of type
295 equality, inequality, and unification — and give implementations
296 differing in simplicity, genericity, and portability.
298 We define the class TypeEq x y b for type equality. The class relates
299 two types x and y to the type HTrue in case the two types are equal;
300 otherwise, the types are related to HFalse. We should point out
301 however groundness issues. If TypeEq is to return HTrue, the types
302 must be ground; TypeEq can return HFalse even for unground types,
303 provided they are instantiated enough to determine that they are not
304 equal. So, TypeEq is total for ground types, and partial for unground
305 types. We also define the class TypeCast x y: a constraint that holds
306 only if the two types x and y are unifiable. Regarding groundness of x
307 and y, the class TypeCast is less restricted than TypeEq. That is,
308 TypeCast x y succeeds even for unground types x and y in case they can
309 be made equal through unification. TypeEq and TypeCast are related to
310 each other as fol- lows. Whenever TypeEq succeeds with HTrue, TypeCast
311 succeeds as well. Whenever TypeEq succeeds with HFalse, TypeCast
312 fails. But for unground types, when TypeCast succeeds, TypeEq might
313 fail. So the two complement each other for unground types. Also,
314 TypeEq is a partial predicate, while TypeCast is a relation. That’s
317 class TypeEq x y b | x y -> b
318 instance TypeEq x x True
319 instance TypeCast False b =>
322 class TypeCast a b | a -> b, b -> a
326 class TypeCast' t a b | t a -> b, t b -> a
328 typeCast' :: t -> a -> b
330 class TypeCast'' t a b | t a -> b, t b -> a
332 typeCast'' :: t -> a -> b
334 instance TypeCast' () a b => TypeCast a b
336 typeCast x = typeCast' () x
338 instance TypeCast'' t a b => TypeCast' t a b
340 typeCast' = typeCast''
342 instance TypeCast'' () a a