++- Array or list sort and reverse

SORT_* :
  ASC
  DESC
;

*_SORT :
  QUICK
  MOVING
  REVERSE
  NO
;

++- Entry points

sort = a order-by + sorted ->
  sorted = array-sort a sort-method order-by
  ' sort-method = sort-method a already-ordered a._
  ' already-ordered = already-ordered a order-by
_
  a : array : <T>
  sorted : array : T
  order-by : SORT_* : {ASC DESC}
;

sort = list order-by + sorted ->
  sorted = list-sort list sort-method order-by
  ' sort-method = sort-method list already-ordered list._
  ' already-ordered = already-ordered list order-by
_
  list : list : <T>
  sorted : list : T : [list]
  order-by : SORT_* : {ASC DESC}
;

++- Entry points w/default values

sort :: _(a : array) SORT_ASC
sort :: _(list : _) SORT_ASC

++- Helper functions

already-ordered sort = a order-by + cntr ->
  do {1.. (a._ - 1)} i ->
    if (order-by = SORT_ASC) ->
      cntr ++ [ a.i < a.(i + 1) ]
    else
      cntr ++ [ a.i > a.(i + 1) ]
    ;
  ;
_
  a : array
  order-by : SORT_* : {ASC DESC}
;

already-ordered sort = list order-by + cntr ->
  prev = . ..

  for list n ->
    x = prev = n

    if (order-by = SORT_ASC) ->
      cntr ++ [ x && x < n ]
    else
      cntr ++ [ x && x > n ]
    ;
  ;
_
  list : _
  order-by : SORT_* : {ASC DESC}
;

++- Action selectors 

sort-method sort = a ordered total ->
  case (total = 0 | total = 1) ->
    NO_SORT
  case (ordered = total - 1) ->
    NO_SORT
  case (ordered = 0) ->
    REVERSE_SORT
  else
    MOVING_SORT
  ;
_
  a : array
;

sort-method sort = list ordered total ->
  case (total = 0 | total = 1) ->
    NO_SORT
  case (ordered = total - 1) ->
    NO_SORT
  case (ordered = 0) ->
    REVERSE_SORT
  else
    QUICK_SORT
  ;
_
  list : _
;

++- Adapters and empty functions

a-sort    array-sort = sort    ++ array-sort
a-reverse array-sort = reverse ++ array-sort
l-sort    list-sort  = sort    ++ list-sort
l-reverse list-sort  = reverse ++ list-sort

array-sort = array MOVING_SORT  -> - a-sort array
list-sort  = list  QUICK_SORT   -> - l-sort list
array-sort = array REVERSE_SORT -> - a-reverse array
list-sort  = list  REVERSE_SORT -> - l-reverse list
array-sort = .     NO_SORT      -> <>
list-sort  = .     NO_SORT      -> <>
