Reduce is a function or method that is used to take the values in an array or a list and apply a function to successive members of the list to produce (or reduce them to), a single value.



Task

Show how reduce (or foldl or foldr etc), work (or would be implemented) in your language.



See also

 Wikipedia article:   Fold
 Wikipedia article:   Catamorphism


 
MODULE Catamorphism;
IMPORT
  Object,
  NPCT:Tools,
  NPCT:Args,
  IntStr,
  Out;
 
TYPE
  BinaryFunc= PROCEDURE (x,y: LONGINT): LONGINT;
 
VAR
  data: POINTER TO ARRAY OF LONGINT;
  i: LONGINT;
 
  PROCEDURE Sum(x,y: LONGINT): LONGINT;
  BEGIN
    RETURN x + y
  END Sum;
 
  PROCEDURE Sub(x,y: LONGINT): LONGINT;
  BEGIN
    RETURN x - y;
  END Sub;
 
  PROCEDURE Mul(x,y: LONGINT): LONGINT;
  BEGIN
    RETURN x * y;
  END Mul;
 
  PROCEDURE Reduce(x: ARRAY OF LONGINT; f: BinaryFunc): LONGINT;
  VAR
    i,res: LONGINT;
  BEGIN
    res := x[0];i := 1;
    WHILE (i < LEN(x)) DO;
      res := f(res,x[i]);
      INC(i)
    END;
    RETURN res
  END Reduce;
 
  PROCEDURE InitData(VAR x: ARRAY OF LONGINT);
  VAR
    i, j: LONGINT;
    res: IntStr.ConvResults;
    aux: Object.CharsLatin1;
  BEGIN
    i := 0;j := 1;
    WHILE (j <= LEN(x)) DO
      aux := Tools.AsString(Args.Get(j));
      IntStr.StrToInt(aux^,x[i],res);
      IF res # IntStr.strAllRight THEN
        Out.String("Incorrect format for data at index ");Out.LongInt(j,0);Out.Ln;
        HALT(1);
      END;
      INC(j);INC(i)
    END
  END InitData;
 
BEGIN
  IF Args.Number() = 1 THEN
    Out.String("Invalid number of arguments. ");Out.Ln;
    HALT(0)
  ELSE
    NEW(data,Args.Number() - 1);
    InitData(data^);
    Out.LongInt(Reduce(data^,Sum),0);Out.Ln;
    Out.LongInt(Reduce(data^,Sub),0);Out.Ln;
    Out.LongInt(Reduce(data^,Mul),0);Out.Ln
  END
END Catamorphism.
 