{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wall #-}
{-# OPTIONS_GHC -Werror=incomplete-patterns #-}
module Fcf.Alg.Sort where
import qualified GHC.TypeLits as TL
import Fcf ( If, Eval, Exp, type (<=<), type (=<<)
, Flip, Not, TyEq, Pure )
import Fcf.Data.List ( ZipWith, Filter, type (++) )
import Fcf.Data.Nat (Nat)
import Fcf.Data.Symbol (Symbol)
import Fcf.Alg.Tree (BTreeF(..))
import Fcf.Alg.Morphism
import Fcf.Alg.Symbol (SymbolOrd)
data ListCmpFnd :: [Ordering] -> Exp Ordering
type instance Eval (ListCmpFnd '[]) = 'EQ
type instance Eval (ListCmpFnd (a ': as)) = Eval
(If (Eval (TyEq a 'EQ))
(ListCmpFnd as)
(Pure a)
)
data ListCmp :: (a -> a -> Exp Ordering) -> [a] -> [a] -> Exp Ordering
type instance Eval (ListCmp f as bs) = Eval (ListCmpFnd =<< ZipWith f as bs)
data ListOrd :: (a -> a -> Exp Ordering) -> [a] -> [a] -> Exp Bool
type instance Eval (ListOrd f as bs) = Eval
(If (Eval (TyEq 'LT (Eval (ListCmp f as bs))))
(Pure 'True)
(Pure 'False)
)
data NatOrd :: Nat -> Nat -> Exp Ordering
type instance Eval (NatOrd a b) = TL.CmpNat a b
data SymbolListOrd :: [Symbol] -> [Symbol] -> Exp Bool
type instance Eval (SymbolListOrd as bs) = Eval (ListOrd SymbolOrd as bs)
data NatListOrd :: [Nat] -> [Nat] -> Exp Bool
type instance Eval (NatListOrd as bs) = Eval (ListOrd NatOrd as bs)
data PartHlp :: (a -> a -> Exp Bool) -> CoAlgebra (BTreeF a) [a]
type instance Eval (PartHlp _ '[]) = 'BEmptyF
type instance Eval (PartHlp smaller (h ': t)) =
'BNodeF h
(Eval (Filter (smaller h) t))
(Eval (Filter (Not <=< smaller h) t))
data Inord :: Algebra (BTreeF a) [a]
type instance Eval (Inord 'BEmptyF) = '[]
type instance Eval (Inord ('BNodeF v l r)) = Eval (l ++ (Eval ('[v] ++ r)))
data Qsort :: (a -> a -> Exp Bool) -> [a] -> Exp [a]
type instance Eval (Qsort cmp lst) = Eval (Hylo Inord (PartCmp cmp) lst)
data PartCmp :: (a -> a -> Exp Bool) -> CoAlgebra (BTreeF a) [a]
type instance Eval (PartCmp cmp coalg) = Eval (PartHlp (Flip cmp) coalg)