1 {- -*- coding: utf-8 -*- -}
7 FunctionalDependencies,
14 module Data.HList.Prelude
51 import Types.Data.Bool
52 import Types.Data.Num hiding ((:*:))
61 deriving (Show, Eq, Ord, Read, Typeable)
71 deriving (Show, Eq, Ord, Read, Typeable)
73 instance HList l => HList (HCons e l)
75 hCons :: HList l => e -> l -> HCons e l
82 class HExtendT e l where
84 (.&.) :: e -> l -> e :&: l
86 instance HExtendT e HNil where
87 type e :&: HNil = HCons e HNil
88 e .&. nil = hCons e nil
90 instance HList l => HExtendT e (HCons e' l) where
91 type e :&: HCons e' l = HCons e (HCons e' l)
92 e .&. HCons e' l = hCons e (hCons e' l)
98 class HAppendT l l' where
100 (.++.) :: l -> l' -> l :++: l'
102 instance HList l => HAppendT HNil l where
106 instance ( HList (l :++: l')
108 ) => HAppendT (HCons e l) l' where
109 type HCons e l :++: l' = HCons e (l :++: l')
110 (HCons e l) .++. l' = hCons e (l .++. l')
113 class ApplyT f a where
115 apply :: f -> a -> Apply f a
116 apply _ _ = undefined
119 class Apply2T f a b where
121 apply2 :: f -> a -> b -> Apply2 f a b
122 apply2 _ _ _ = undefined
127 instance ApplyT Id a where
132 data HAppendA = HAppendA
134 instance HAppendT a b => Apply2T HAppendA a b where
135 type Apply2 HAppendA a b = a :++: b
136 apply2 _ a b = a .++. b
139 class HFoldrT f v l where
141 hFoldr :: f -> v -> l -> HFoldr f v l
143 instance HFoldrT f v HNil where
144 type HFoldr f v HNil = v
147 instance ( HFoldrT f v l
148 , Apply2T f e (HFoldr f v l)
149 ) => HFoldrT f v (HCons e l) where
150 type HFoldr f v (HCons e l) = Apply2 f e (HFoldr f v l)
151 hFoldr f v (HCons e l) = apply2 f e (hFoldr f v l)
154 class HConcatT ls where
156 hConcat :: ls -> HConcat ls
158 instance HFoldrT HAppendA HNil ls => HConcatT ls where
159 type HConcat ls = HFoldr HAppendA HNil ls
160 hConcat ls = hFoldr HAppendA hNil ls
163 class HMapT f l where
165 hMap :: f -> l -> HMap f l
167 instance HMapT f HNil where
168 type HMap f HNil = HNil
171 instance ( ApplyT f x
174 ) => HMapT f (HCons x xs) where
175 type HMap f (HCons x xs) = HCons (Apply f x) (HMap f xs)
176 hMap f (HCons x xs) = hCons (apply f x) (hMap f xs)
180 type instance HAll f HNil = True
181 type instance HAll f (HCons x xs) = If (Apply f x) (HAll f xs) False
184 type family HLength l
185 type instance HLength HNil = D0
186 type instance HLength (HCons e l) = Succ (HLength l)
191 -- HOccursMany (zero or more)
192 class HOccursMany e l where
193 hOccursMany :: l -> [e]
195 instance HOccursMany e HNil where
201 => HOccursMany e (HCons e l)
203 hOccursMany (HCons e l) = e : hOccursMany l
208 => HOccursMany e (HCons e' l)
210 hOccursMany (HCons _ l) = hOccursMany l
212 -- HOccursMany1 (one or more)
213 class HOccursMany1 e l where
214 hOccursMany1 :: l -> [e]
216 instance Fail (TypeNotFound e) => HOccursMany1 e HNil where
217 hOccursMany1 _ = undefined
222 => HOccursMany1 e (HCons e l)
224 hOccursMany1 (HCons e l) = e : hOccursMany l
229 => HOccursMany1 e (HCons e' l)
231 hOccursMany1 (HCons _ l) = hOccursMany1 l
233 -- HOccursOpt (zero or one)
234 class HOccursOpt e l where
235 hOccursOpt :: l -> Maybe e
237 instance HOccursOpt e HNil where
238 hOccursOpt _ = Nothing
240 instance HOccursNot e l => HOccursOpt e (HCons e l) where
241 hOccursOpt (HCons e _) = Just e
243 instance HOccursOpt e l => HOccursOpt e (HCons e' l) where
244 hOccursOpt (HCons _ l) = hOccursOpt l
247 class HOccurs e l where
252 instance Fail (TypeNotFound e) => HOccurs e HNil
259 => HOccurs e (HCons e l)
261 hOccurs (HCons e _) = e
266 => HOccurs e (HCons e' l)
268 hOccurs (HCons _ l) = hOccurs l
273 instance HOccursNot e HNil
274 instance Fail (TypeFound e) => HOccursNot e (HCons e l)
275 instance HOccursNot e l => HOccursNot e (HCons e' l)
279 "Strongly Typed Heterogeneous Collections"
284 ==========================
285 9 By chance or by design?
287 We will now discuss the issues surrounding the definition of type
288 equality, inequality, and unification — and give implementations
289 differing in simplicity, genericity, and portability.
291 We define the class TypeEq x y b for type equality. The class relates
292 two types x and y to the type HTrue in case the two types are equal;
293 otherwise, the types are related to HFalse. We should point out
294 however groundness issues. If TypeEq is to return HTrue, the types
295 must be ground; TypeEq can return HFalse even for unground types,
296 provided they are instantiated enough to determine that they are not
297 equal. So, TypeEq is total for ground types, and partial for unground
298 types. We also define the class TypeCast x y: a constraint that holds
299 only if the two types x and y are unifiable. Regarding groundness of x
300 and y, the class TypeCast is less restricted than TypeEq. That is,
301 TypeCast x y succeeds even for unground types x and y in case they can
302 be made equal through unification. TypeEq and TypeCast are related to
303 each other as fol- lows. Whenever TypeEq succeeds with HTrue, TypeCast
304 succeeds as well. Whenever TypeEq succeeds with HFalse, TypeCast
305 fails. But for unground types, when TypeCast succeeds, TypeEq might
306 fail. So the two complement each other for unground types. Also,
307 TypeEq is a partial predicate, while TypeCast is a relation. That’s
310 class TypeEq x y b | x y -> b
311 instance TypeEq x x True
312 instance TypeCast False b =>
315 class TypeCast a b | a -> b, b -> a
319 class TypeCast' t a b | t a -> b, t b -> a
321 typeCast' :: t -> a -> b
323 class TypeCast'' t a b | t a -> b, t b -> a
325 typeCast'' :: t -> a -> b
327 instance TypeCast' () a b => TypeCast a b
329 typeCast x = typeCast' () x
331 instance TypeCast'' t a b => TypeCast' t a b
333 typeCast' = typeCast''
335 instance TypeCast'' () a a