unison/unison-src/tests/soe2.u

48 lines
1.2 KiB
Plaintext

use Universal == <
use Optional None Some
uncons : [a] -> Optional (a, [a])
uncons a = match at 0 a with
None -> None
Some hd -> Some (hd, drop 1 a)
merge : (a -> a -> Boolean) -> [a] -> [a] -> [a]
merge lte a b =
go acc a b = match (uncons a, uncons b) with
(None, _) -> acc ++ b
(_, None) -> acc ++ a
(Some (h1,t1), Some (h2,t2)) ->
if lte h1 h2 then go (snoc acc h1) (drop 1 a) b
else go (snoc acc h2) a (drop 1 b)
go [] a b
-- let's make sure it works
> merge (<) [1,3,4,99,504,799] [0,19,22,23]
isEmpty : [a] -> Boolean
isEmpty a = size a == 0
halve : [a] -> Optional ([a], [a])
halve as =
if isEmpty as then None
else Some (take (size as / 2) as, drop (size as / 2) as)
sort : (a -> a -> Boolean) -> [a] -> [a]
sort lte as = if size as < 2 then as else match halve as with
None -> as
Some (left, right) ->
l = sort lte left
r = sort lte right
merge lte l r
-- let's make sure it works
> sort (<) [3,2,1,1,2,3,9182,1,2,34,1,23]
-- > sort (<) ["Dave", "Carol", "Eve", "Alice", "Bob", "Francis", "Hal", "Illy", "Joanna", "Greg", "Karen"]
-- > sort (<) [3,2,1,1,2,3,9182,1,2,34,1,"oops"]
-- > merge (<) [1,4,5,90,102] ["a", "b"]