A format for expressing an ordered list of integers is to use a comma separated list of either

 individual integers
 Or a range of integers denoted by the starting integer separated from the end integer in the range by a dash, '-'. (The range includes all integers in the interval including both endpoints)
 The range syntax is to be used only for, and for every range that expands to more than two values.
Example

The list of integers:

 -6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20
Is accurately expressed by the range expression:

 -6,-3-1,3-5,7-11,14,15,17-20
(And vice-versa).

Task

 Create a function that takes a list of integers in increasing order and returns a correctly formatted string in the range format. 
 Use the function to compute and print the range formatted version of the following ordered list of integers. (The correct answer is: 0-2,4,6-8,11,12,14-25,27-33,35-39).


    0,  1,  2,  4,  6,  7,  8, 11, 12, 14,
   15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
   25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
   37, 38, 39

 Show the output of your program.


Related task

   Range expansion


###
  REQUIRES(MODE SCALAR, OP(SCALAR,SCALAR)BOOL =, OP(SCALAR,SCALAR)SCALAR +);
###
MODE SCALARLIST = FLEX[0]SCALAR;
MODE YIELDINT = PROC(SCALAR)VOID;
 
################################################################
# Declarations for manipulating lists of range pairs [lwb:upb] #
################################################################
MODE RANGE = STRUCT(SCALAR lwb, upb);
MODE RANGELIST = FLEX[0]RANGE;
MODE YIELDRANGE = PROC(RANGE)VOID;
 
PROC range repr = (RANGE range)STRING: (
  STRING lwb := whole(lwb OF range,0);
  IF lwb OF range = upb OF range THEN
    lwb
  ELSE
    # "["+lwb+":"+whole(upb OF range,0)+"]"  #
    lwb+"-"+whole(upb OF range,0)
  FI
);
 
# OP REPR = (RANGE range)STRING: range repr(range); # # firmly related to UNIRANGE #
 
######################################################################
# Declarations for manipulating lists containing pairs AND lone INTs #
######################################################################
MODE UNIRANGE = UNION(SCALAR, RANGE);
MODE UNIRANGELIST = FLEX[0]UNIRANGE;
MODE YIELDUNIRANGE = PROC(UNIRANGE)VOID;
 
PROC unirange repr = (UNIRANGE unirange)STRING:
  CASE unirange IN
    (RANGE range): range repr(range),
    (SCALAR scalar): whole(scalar,0)
  ESAC;
 
OP (UNIRANGE)STRING REPR = unirange repr; # alias #
 
# The closest thing Algol68 has to inheritance is the UNION #
MODE UNIRANGELISTS = UNION(UNIRANGELIST, RANGELIST, SCALARLIST);
 
PROC unirange list repr = (UNIRANGELIST unirange list)STRING: (
### Produce a STRING representation of a UNIRANGELIST ###
  STRING out # := "("#, sep := "";
  FOR key FROM LWB unirange list TO UPB unirange list DO
    out +:= sep + REPR unirange list[key];
    sep := "," # +" " #
  OD;
  out # +")" #
);
 
OP (UNIRANGELIST)STRING REPR = unirange list repr; # alias #