I'm having some fun with type functions, type families and stuff like
that. Basically, I've recoded the HList package using type families
instead of functional dependencies (for fun). Here's a snippet of it:
------
infixr 5 .++.
infixr 5 :++:
data Nil = Nil deriving Show
data Cons e l = Cons e l deriving Show
class TypeList l
instance TypeList Nil
instance TypeList l => TypeList (Cons e l)
type e :++: l = Cons e l
(.++.) :: TypeList l => e -> l -> Cons e l
(.++.) = Cons
class HApply f a where
type HApplyT f a
hApply :: f -> a -> HApplyT f a
class HFoldr f v l where
type HFoldrT f v l
hFoldr :: f -> v -> l -> HFoldrT f v l
instance HFoldr f v Nil where
type HFoldrT f v Nil = v
hFoldr _ v _ = v
instance (HApply f (e, HFoldrT f v l), HFoldr f v l) => HFoldr f v
(Cons e l) where
type HFoldrT f v (Cons e l) = HApplyT f (e, HFoldrT f v l)
hFoldr f v (Cons e l) = hApply f (e, hFoldr f v l)
class HAppend l l' where
type HAppendT l l'
hAppend :: l -> l' -> HAppendT l l'
instance (TypeList l, TypeList l', HFoldr ApplyCons l' l) => HAppend l
l' where
type HAppendT l l' = HFoldrT ApplyCons l' l
hAppend l l' = hFoldr ApplyCons l' l
data ApplyCons = ApplyCons
instance HApply ApplyCons (e, l) where
type HApplyT ApplyCons (e, l) = Cons e l
hApply _ (e, l) = Cons e l
------
But now I have a problem; I need to have an HSplit function, which,
for a type that matches HAppendT l l', will give me (l, l').
So I tried something like that:
class HSplit l where
type HSplitT l
hSplit :: l -> HSplitT l
instance HSplit (HAppendT l l') where
type HSplitT (HAppendT l l') = (l, l')
hSplit = undefined
GHC gives me the error : Illegal type synonym family application in
instance: HAppendT l l' In the instance declaration for `HSplit
(HAppendT l l')'
I've tried some other things, but to no avail. Is what I am trying to
do feasible?
Thanks for your help.