{-# OPTIONS --sized-types #-} module SizedTypesMergeSort where postulate Size : Set _^ : Size -> Size ∞ : Size {-# BUILTIN SIZE Size #-} {-# BUILTIN SIZESUC _^ #-} {-# BUILTIN SIZEINF ∞ #-} -- sized lists data List (A : Set) : {_ : Size} -> Set where [] : {size : Size} -> List A {size ^} _::_ : {size : Size} -> A -> List A {size} -> List A {size ^} -- CPS split split : {A : Set}{i : Size} -> List A {i} -> {C : Set} -> (List A {i} -> List A {i} -> C) -> C split [] k = k [] [] split (x :: xs) k = split xs (\ l r -> k (x :: r) l) module Sort (A : Set) (compare : A -> A -> {B : Set} -> B -> B -> B) where {- merge is currently rejected by the termination checker it would be nice if it worked see test/succeed/SizedTypesMergeSort.agda -} merge : List A -> List A -> List A merge [] ys = ys merge xs [] = xs merge (x :: xs) (y :: ys) = compare x y (x :: merge xs (y :: ys)) (y :: merge (x :: xs) ys) sort : {i : Size} -> List A {i} -> List A sort [] = [] sort (x :: []) = x :: [] sort (x :: (y :: xs)) = split xs (\ l r -> merge (sort (x :: l)) (sort (y :: r)))