egison-3.3.14: lib/core/order.egi
;;;;;
;;;;;
;;;;; Order
;;;;;
;;;;;
(define $ordering
(algebraic-data-matcher
{<less> <equal> <greater>}))
(define $compare
(lambda [$m $n]
(if (lt? m n)
<Less>
(if (eq? m n)
<Equal>
<Greater>))))
(define $min
(lambda [$ns]
(foldl' (lambda [$x $y] (if (lt? x y) x y)) (car ns) (cdr ns))))
(define $max
(lambda [$ns]
(foldl' (lambda [$x $y] (if (gt? x y) x y)) (car ns) (cdr ns))))
(define $min-and-max
(lambda [$ns]
(foldl' (lambda [$ret $x]
(match ret [integer integer]
{[[$min $max] (if (lt? x min) [x max]
(if (gt? x max) [min x]
[min max]))]}))
[(car ns) (car ns)]
(cdr ns))))
(define $split-by-ordering (split-by-ordering/f compare $ $))
(define $split-by-ordering/f
(lambda [$f $p $xs]
(match xs (list something)
{[<nil> [{} {} {}]]
[<cons $x $rs>
(let {[[$ys1 $ys2 $ys3] (split-by-ordering/f f p rs)]}
(match (f x p) ordering
{[<less> [{x @ys1} ys2 ys3]]
[<equal> [ys1 {x @ys2} ys3]]
[<greater> [ys1 ys2 {x @ys3}]]}))]})))
(define $qsort (qsort/f compare $))
(define $qsort/f
(lambda [$f $xs]
(match xs (list something)
{[<nil> {}]
[<cons $x <nil>> {x}]
[_ (let {[$n (length xs)]}
(let {[$p (nth (quotient n 2) xs)]}
(let {[[$ys1 $ys2 $ys3] (split-by-ordering/f f p xs)]}
{@(qsort/f f ys1) @ys2 @(qsort/f f ys3)})))]})))