module Data.HList.HSort where
import Data.HList.HList
import Data.HList.FakePrelude
import Data.HList.Label3
#if __GLASGOW_HASKELL__ > 707
import GHC.TypeLits (type (<=?), CmpSymbol)
instance ((x <=? y) ~ b) => HEqBy HLeFn x y b
instance (HEq (CmpSymbol x y) GT nb, HNot nb ~ b) => HEqBy HLeFn x y b
#endif
data HLeFn
instance HEqByFn HLeFn
instance (HLe x y ~ b) => HEqBy HLeFn x y b
instance HEqBy HLeFn x y b => HEqBy HLeFn (Tagged x v) (Tagged y w) b
instance HEqBy HLeFn x y b => HEqBy HLeFn (Label x) (Label y) b
instance HEqBy HLeFn x y b => HEqBy HLeFn (Proxy x) (Proxy y) b
instance (HEqBy HLeFn n m b, ns ~ ns')
=> HEqBy HLeFn (Lbl n ns desc) (Lbl m ns' desc') b
data HDown a
instance HEqByFn a => HEqByFn (HDown a)
instance HEqBy f y x b => HEqBy (HDown f) x y b
data HNeq le
instance HEqByFn a => HEqByFn (HNeq a)
instance (HEqBy le y x b1, HNot b1 ~ b2) => HEqBy (HNeq le) x y b2
class HEqByFn le => HIsAscList le (xs :: [*]) (b :: Bool) | le xs -> b
instance HEqByFn le => HIsAscList le '[x] True
instance HEqByFn le => HIsAscList le '[] True
instance (HEqBy le x y b1,
HIsAscList le (y ': ys) b2,
HAnd b1 b2 ~ b3) => HIsAscList le (x ': y ': ys) b3
class (SameLength a b, HEqByFn le) => HSortBy le (a :: [*]) (b :: [*]) | le a -> b where
hSortBy :: Proxy le -> HList a -> HList b
type HSort x y = HSortBy HLeFn x y
hSort :: HSort x y => HList x -> HList y
hSort xs = hSortBy (Proxy :: Proxy HLeFn) xs
instance (SameLength a b,
HIsAscList le a ok,
HSortBy1 ok le a b) => HSortBy le a b where
hSortBy = hSortBy1 (Proxy :: Proxy ok)
instance HSortBy1 True le a a where
hSortBy1 _ _ a = a
instance HQSortBy le a b => HSortBy1 False le a b where
hSortBy1 _ = hQSortBy
class HSortBy1 ok le (a :: [*]) (b :: [*]) | ok le a -> b where
hSortBy1 :: Proxy ok -> Proxy le -> HList a -> HList b
class HEqByFn le => HMSortBy le (a :: [*]) (b :: [*]) | le a -> b where
hMSortBy :: Proxy le -> HList a -> HList b
instance HEqByFn le => HMSortBy le '[] '[] where hMSortBy _ x = x
instance HEqByFn le => HMSortBy le '[x] '[x] where hMSortBy _ x = x
instance (HSort2 b x y ab, HEqBy le x y b) =>
HMSortBy le '[x,y] ab where
hMSortBy _ (a `HCons` b `HCons` HNil) = hSort2 (Proxy :: Proxy b) a b
class HSort2 b x y ab | b x y -> ab where
hSort2 :: Proxy b -> x -> y -> HList ab
instance HSort2 True x y '[x,y] where
hSort2 _ x y = x `HCons` y `HCons` HNil
instance HSort2 False x y '[y,x] where
hSort2 _ x y = y `HCons` x `HCons` HNil
instance (HMerge le xs' ys' sorted,
HMSortBy le ys ys',
HMSortBy le xs xs',
HLengthEq (a ': b ': c ': cs) n2,
HDiv2 n2 ~ n,
HSplitAt n (a ': b ': c ': cs) xs ys)
=> HMSortBy le (a ': b ': c ': cs) sorted where
hMSortBy le abbs = case hSplitAt (Proxy :: Proxy n) abbs of
(xs, ys) -> hMerge le (hMSortBy le xs) (hMSortBy le ys)
class HMerge le x y xy | le x y -> xy where
hMerge :: Proxy le -> HList x -> HList y -> HList xy
instance HMerge le '[] '[] '[] where hMerge _ _ _ = HNil
instance HMerge le (x ': xs) '[] (x ': xs) where hMerge _ x _ = x
instance HMerge le '[] (x ': xs) (x ': xs) where hMerge _ _ x = x
instance (HEqBy le x y b,
HMerge1 b (x ': xs) (y ': ys) (l ': ls) hhs,
HMerge le ls hhs srt)
=> HMerge le (x ': xs) (y ': ys) (l ': srt) where
hMerge le xxs yys = case hMerge1 (Proxy :: Proxy b) xxs yys of
(HCons l ls, hhs) -> l `HCons` hMerge le ls hhs
type HMerge1 b x y min max = (HCond b (HList x) (HList y) (HList min),
HCond b (HList y) (HList x) (HList max))
hMerge1 b x y = (hCond b x y, hCond b y x)
class HQSortBy le (a :: [*]) (b :: [*]) | le a -> b where
hQSortBy :: Proxy le -> HList a -> HList b
instance HQSortBy le '[] '[] where hQSortBy _ x = x
instance HQSortBy le '[x] '[x] where hQSortBy _ x = x
instance (HPartitionEq le a (b ': bs) bGeq bLt,
HQSortBy le bLt sortedLt,
HQSortBy le bGeq sortedGeq,
HAppendListR sortedLt (a ': sortedGeq) ~ sorted,
HAppendList sortedLt (a ': sortedGeq)) =>
HQSortBy le (a ': b ': bs) sorted where
hQSortBy le (a `HCons` xs) = case hPartitionEq le (Proxy :: Proxy a) xs of
(g,l) -> hQSortBy le l `hAppendList` (a `HCons` hQSortBy le g)
class HEqByFn lt => HSetBy lt (ps :: [*])
instance (HSortBy lt ps ps', HAscList lt ps') => HSetBy lt ps
class HSetBy (HNeq HLeFn) ps => HSet (ps :: [*])
instance HSetBy (HNeq HLeFn) ps => HSet ps
class HIsSet (ps :: [*]) (b :: Bool) | ps -> b
instance HIsSetBy (HNeq HLeFn) ps b => HIsSet ps b
class HEqByFn lt => HIsSetBy lt (ps :: [*]) (b :: Bool) | lt ps -> b
instance (HSortBy lt ps ps', HIsAscList lt ps' b) => HIsSetBy lt ps b
class HEqByFn le => HAscList le (ps :: [*])
instance HAscList0 le ps ps => HAscList le ps
class HEqByFn le => HAscList0 le (ps :: [*]) (ps0 :: [*])
class HEqByFn le => HAscList1 le (b :: Bool) (ps :: [*]) (ps0 :: [*])
instance (HAscList1 le b (y ': ys) ps0, HEqBy le x y b)
=> HAscList0 le (x ': y ': ys) ps0
instance HEqByFn le => HAscList0 le '[] ps0
instance HEqByFn le => HAscList0 le '[x] ps0
instance ( Fail '("Duplicated element", y, "using le", le, "in", ys0), HEqByFn le )
=> HAscList1 le False (y ': ys) ys0
instance HAscList0 le ys ys0 => HAscList1 le True ys ys0