inch-0.1.0: examples/MergeSort.hs
{-# OPTIONS_GHC -F -pgmF inch #-}
{-# LANGUAGE RankNTypes, GADTs, KindSignatures, ScopedTypeVariables,
NPlusKPatterns #-}
module MergeSort where
import Vectors
comp f g x = f (g x)
data DTree :: * -> Integer -> * where
Empty :: DTree a 0
Leaf :: a -> DTree a 1
Even :: forall a (n :: Integer) . 1 <= n =>
DTree a n -> DTree a n -> DTree a (2*n)
Odd :: forall a (n :: Integer) . 1 <= n =>
DTree a (n+1) -> DTree a n -> DTree a (2*n+1)
deriving Show
insert :: forall a (n :: Integer) . a -> DTree a n -> DTree a (n+1)
insert i Empty = Leaf i
insert i (Leaf j) = Even (Leaf i) (Leaf j)
insert i (Even l r) = Odd (insert i l) r
insert i (Odd l r) = Even l (insert i r)
merge :: forall (m n :: Integer) .
Vec Integer m -> Vec Integer n -> Vec Integer (m+n)
merge VNil ys = ys
merge xs VNil = xs
merge (VCons x xs) (VCons y ys) | (<=) x y = VCons x (merge xs (VCons y ys))
| otherwise = VCons y (merge (VCons x xs) ys)
build = vifold Empty insert
flatten :: forall (n :: Integer) . DTree Integer n -> Vec Integer n
flatten Empty = VNil
flatten (Leaf i) = VCons i VNil
flatten (Even l r) = merge (flatten l) (flatten r)
flatten (Odd l r) = merge (flatten l) (flatten r)
sort = comp flatten build
data OVec :: Integer -> Integer -> Integer -> * where
ONil :: forall (l u :: Integer) . l <= u => OVec 0 l u
OCons :: forall (n l u :: Integer) . pi (x :: Integer) . l <= x =>
OVec n x u -> OVec (n+1) l u
deriving Show
ltCompare :: forall a. pi (x y :: Integer) . (x <= y => a) -> (x > y => a) -> a
ltCompare {x} {y} l g | {x <= y} = l
ltCompare {x} {y} l g | {x > y} = g
omerge :: forall (m n l u :: Integer) . OVec m l u -> OVec n l u -> OVec (m+n) l u
omerge ONil ys = ys
omerge xs ONil = xs
omerge (OCons {x} xs) (OCons {y} ys)
= ltCompare {x} {y} (OCons {x} (omerge xs (OCons {y} ys)))
(OCons {y} (omerge (OCons {x} xs) ys))
data In :: Integer -> Integer -> * where
In :: forall (l u :: Integer) . pi (x :: Integer) . (l <= x, x <= u) => In l u
deriving Show
oflatten :: forall (n l u :: Integer) . l <= u => DTree (In l u) n -> OVec n l u
oflatten Empty = ONil
oflatten (Leaf (In {i})) = OCons {i} ONil
oflatten (Even l r) = omerge (oflatten l) (oflatten r)
oflatten (Odd l r) = omerge (oflatten l) (oflatten r)
osort = comp oflatten build