Catamorphism: Difference between revisions

61,388 bytes added ,  3 months ago
m
No edit summary
 
(144 intermediate revisions by 49 users not shown)
Line 1:
{{task}}
 
''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.
 
;Cf.
* [[wp:Fold (higher-order function)|Fold]]
* [[wp:Catamorphism|Catamorphism]]
 
;See also:
* Wikipedia article:   [[wp:Fold (higher-order function)|Fold]]
* Wikipedia article:   [[wp:Catamorphism|Catamorphism]]
<br><br>
=={{header|11l}}==
<syntaxhighlight lang="11l">print((1..3).reduce((x, y) -> x + y))
print((1..3).reduce(3, (x, y) -> x + y))
print([1, 1, 3].reduce((x, y) -> x + y))
print([1, 1, 3].reduce(2, (x, y) -> x + y))</syntaxhighlight>
{{out}}
<pre>
6
9
5
7
</pre>
=={{header|6502 Assembly}}==
{{works with|https://skilldrick.github.io/easy6502/ Easy6502}}
<syntaxhighlight lang="6502asm">define catbuf $10
define catbuf_temp $12
 
ldx #0
ramloop:
txa
sta $00,x
inx
cpx #$10
bne ramloop
;load zero page addresses $00-$0f with values equal
;to that address
 
 
ldx #0 ;zero X
loop_cata:
lda $00,x ;load the zeroth element
clc
adc $01,x ;add the first to it.
inx
inx ;inx twice. Otherwise the same element
;would get added twice
sta catbuf_temp ;store in temp ram
lda catbuf
clc
adc catbuf_temp ;add to previously stored value
sta catbuf ;store in result
cpx #$10 ;is the range over?
bne loop_cata ;if not, loop again
 
ldx #$00
lda catbuf
sta $00,x
;store the sum in the zeroth entry of the range
 
inx
lda #$00
 
;now clear the rest of zeropage, leaving only the sum
 
clear_ram:
sta $00,x
inx
cpx #$ff
bne clear_ram</syntaxhighlight>
=={{header|ABAP}}==
This works in ABAP version 7.40 and above.
 
<syntaxhighlight lang="abap">
report z_catamorphism.
 
data(numbers) = value int4_table( ( 1 ) ( 2 ) ( 3 ) ( 4 ) ( 5 ) ).
 
write: |numbers = { reduce string(
init output = `[`
index = 1
for number in numbers
next output = cond string(
when index eq lines( numbers )
then |{ output }, { number } ]|
when index > 1
then |{ output }, { number }|
else |{ output } { number }| )
index = index + 1 ) }|, /.
 
write: |sum(numbers) = { reduce int4(
init result = 0
for number in numbers
next result = result + number ) }|, /.
 
write: |product(numbers) = { reduce int4(
init result = 1
for number in numbers
next result = result * number ) }|, /.
 
data(strings) = value stringtab( ( `reduce` ) ( `in` ) ( `ABAP` ) ).
 
write: |strings = { reduce string(
init output = `[`
index = 1
for string in strings
next output = cond string(
when index eq lines( strings )
then |{ output }, { string } ]|
when index > 1
then |{ output }, { string }|
else |{ output } { string }| )
index = index + 1 ) }|, /.
 
write: |concatenation(strings) = { reduce string(
init text = ``
for string in strings
next text = |{ text } { string }| ) }|, /.
</syntaxhighlight>
 
{{out}}
<pre>
numbers = [ 1, 2, 3, 4, 5 ]
 
sum(numbers) = 15
 
product(numbers) = 120
 
strings = [ reduce, in, ABAP ]
 
concatenation(strings) = reduce in ABAP
</pre>
=={{header|Ada}}==
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
 
procedure Catamorphism is
Line 38 ⟶ 163:
NIO.Put(Fold_Left(Add'Access, (1,2,3,4)), Width => 3);
NIO.Put(Fold_Left(Mul'Access, (1,2,3,4)), Width => 3);
end Catamorphism;</langsyntaxhighlight>
 
{{out}}
 
<pre> 1 4 10 24</pre>
=={{header|Aime}}==
<syntaxhighlight lang="aime">integer s;
 
s = 0;
list(1, 2, 3, 4, 5, 6, 7, 8, 9).ucall(add_i, 1, s);
o_(s, "\n");</syntaxhighlight>
{{Out}}
<pre>45</pre>
=={{header|ALGOL 68}}==
<langsyntaxhighlight lang="algol68"># applies fn to successive elements of the array of values #
# the result is 0 if there are no values #
PROC reduce = ( []INT values, PROC( INT, INT )INT fn )INT:
Line 64 ⟶ 196:
; print( ( reduce( ( 1, 2, 3, 4, 5 ), ( INT a, b )INT: a * b ), newline ) ) # product #
; print( ( reduce( ( 1, 2, 3, 4, 5 ), ( INT a, b )INT: a - b ), newline ) ) # difference #
END</langsyntaxhighlight>
{{out}}
<pre>
Line 71 ⟶ 203:
-13
</pre>
=={{header|APL}}==
<em>Reduce</em> is a built-in APL operator, written as <code>/</code>.
 
<syntaxhighlight lang="apl"> +/ 1 2 3 4 5 6 7
28
×/ 1 2 3 4 5 6 7
5040</syntaxhighlight>
 
For built-in functions, the seed value is automatically chosen to make sense.
 
<syntaxhighlight lang="apl"> +/⍬
0
×/⍬
1
⌈/⍬ ⍝ this gives the minimum supported value
¯1.797693135E308</syntaxhighlight>
 
For user-supplied functions, the last element in the list is considered the seed.
If <code>F/</code> is called with a list of only one element, <code>F</code> itself is never
called, and calling <code>F/</code> with the empty list is an error.
 
<syntaxhighlight lang="apl"> {⎕←'Input:',⍺,⍵ ⋄ ⍺+⍵}/ 1 2 3 4 5
Input: 4 5
Input: 3 9
Input: 2 12
Input: 1 14
15
{⎕←'Input:',⍺,⍵ ⋄ ⍺+⍵}/ 1
1
{⎕←'Input:',⍺,⍵ ⋄ ⍺+⍵}/ ⍬
DOMAIN ERROR</syntaxhighlight>
=={{header|AppleScript}}==
{{Trans|JavaScript}}
 
Iteratively implemented reduce()'''foldl''' and reduceRight()'''foldr''', using the same 'callBack' argument sequence as JavaScript.in Notethe thatcorresponding to obtain first-class functionsJavaScript fromarray user-defined AppleScript handlers we have tomethods 'lift''reduce()''' themand into script objects'''reduceRight()'''.
 
(Note that to obtain first-class functions from user-defined AppleScript handlers, we have to 'lift' them into script objects).
<lang AppleScript>on run {}
set lst to {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
{reduce(sum_, 0, lst), ¬
reduce(product_, 1, lst), ¬
reduceRight(append_, "", lst)}
--> {55, 3628800, "10987654321"}
end run
 
<syntaxhighlight lang="applescript">---------------------- CATAMORPHISMS ---------------------
 
-- the arguments available to the called function f(a, x, i, l) are
-- va: current accumulator value
-- x: current item in list
-- i: [ 1-based index in list ] optional
-- l: [ a reference to the list itself ] optional
 
-- reducefoldl :: (a -> b -> a) -> a -> [b] -> a
on reducefoldl(f, startValue, xs)
set mf totell mReturn(f)
set v to startValue
set vlng to startValuelength of xs
repeat with i from 1 to lng
set lng to length of xs
set v to |λ|(v, item i of xs, i, xs)
repeat with i from 1 to lng
end repeat
set v to mf's lambda(v, item i of xs, i, xs)
end repeat return v
returnend vtell
end reducefoldl
 
 
-- the arguments available to the called function f(a, x, i, l) are
-- va: current accumulator value
-- x: current item in list
-- i: [ 1-based index in list ] optional
-- l: [ a reference to the list itself ] optional
 
-- reduceRightfoldr :: (a -> b -> a) -> a -> [b] -> a
on reduceRightfoldr(f, startValue, xs)
set mf totell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from lng to 1 by -1
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
end foldr
 
 
--- OTHER FUNCTIONS DEFINED IN TERMS OF FOLDL AND FOLDR --
 
-- concat :: [String] -> string
on concat(xs)
foldl(my append, "", xs)
end concat
 
 
-- product :: Num a => [a] -> a
on product(xs)
script
on |λ|(a, b)
a * b
end |λ|
end script
foldr(result, 1, xs)
set v to startValue
end product
set lng to length of xs
repeat with i from lng to 1 by -1
set v to mf's lambda(v, item i of xs, i, xs)
end repeat
return v
end reduceRight
 
 
-- str :: a -> String
on str(x)
x as string
end str
 
 
-- An ordinary AppleScript handler function
-- liftedsum into:: Num a script which is=> [a] first-class> objecta
on mReturnsum(fxs)
if class of f is script then return f
script
propertyon lambda|λ|(a, : fb)
a + b
end |λ|
end script
end mReturn
foldl(result, 0, xs)
end sum
 
on sum_(a, b)
a + b
end sum_
 
--------------------------- TEST -------------------------
on product_(a, b)
on run
a * b
set xs to {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
end product_
{sum(xs), product(xs), concat(map(str, xs))}
--> {55, 3628800, "10987654321"}
end run
 
 
-------------------- GENERIC FUNCTIONS -------------------
 
-- append :: String -> String -> String
on append_(a, b)
on append(a, b)
a & b
end append_append
 
</lang>
 
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
-- The list obtained by applying f
-- to each element of xs.
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map
 
 
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn</syntaxhighlight>
{{out}}
<pre>{55, 3628800, "12345678910"}</pre>
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">; find the sum, with seed:0 (default)
<pre>{55, 3628800, "10987654321"}</pre>
print fold [1 2 3 4] => add
 
; find the product, with seed:1
=={{header|Bracmat}}==
print fold [1 2 3 4] .seed:1 => mul</syntaxhighlight>
<lang bracmat>( ( fold
 
= f xs init first rest
{{out}}
. !arg:(?f.?xs.?init)
 
& ( !xs:&!init
<pre>10
| !xs:%?first ?rest
24</pre>
& !f$(!first.fold$(!f.!rest.!init))
=={{header|BASIC}}==
)
==={{header|BASIC256}}===
)
{{trans|Run BASIC}}
& out
<syntaxhighlight lang="basic256">arraybase 1
$ ( fold
global n
$ ( (=a b.!arg:(?a.?b)&!a+!b)
dim n = . {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
 
. 0
print " +: "; " "; cat(10, "+")
print " -: "; " "; cat(10, "-")
)
print " *: "; " "; cat(10, "*")
& (product=a b.!arg:(?a.?b)&!a*!b)
print " /: "; " "; cat(10, "/")
& out$(fold$(product.1 2 3 4 5.1))
print " ^: "; " "; cat(10, "^")
);</lang>
print "max: "; " "; cat(10, "max")
Output:
print "min: "; " "; cat(10, "min")
<pre>15
print "avg: "; " "; cat(10, "avg")
120</pre>
print "cat: "; " "; cat(10, "cat")
end
 
function min(a, b)
if a < b then return a else return b
end function
function max(a, b)
if a > b then return a else return b
end function
 
function cat(cont, op$)
temp = n[1]
temp$ = ""
for i = 2 to cont
if op$ = "+" then temp += n[i]
if op$ = "-" then temp -= n[i]
if op$ = "*" then temp *= n[i]
if op$ = "/" then temp /= n[i]
if op$ = "^" then temp = temp ^ n[i]
if op$ = "max" then temp = max(temp, n[i])
if op$ = "min" then temp = min(temp, n[i])
if op$ = "avg" then temp += n[i]
if op$ = "cat" then temp$ += string(n[i])
next i
if op$ = "avg" then temp /= cont
if op$ = "cat" then temp = int(string(n[1]) + temp$)
return temp
end function</syntaxhighlight>
 
==={{header|Chipmunk Basic}}===
{{trans|Run BASIC}}
{{works with|Chipmunk Basic|3.6.4}}
<syntaxhighlight lang="qbasic">100 DIM n(10)
110 FOR i = 1 TO 10 : n(i) = i : NEXT i
120 SUB cat(cnt,op$)
130 temp = n(1)
140 FOR i = 2 TO cnt
150 IF op$ = "+" THEN temp = temp+n(i)
160 IF op$ = "-" THEN temp = temp-n(i)
170 IF op$ = "*" THEN temp = temp*n(i)
180 IF op$ = "/" THEN temp = temp/n(i)
190 IF op$ = "^" THEN temp = temp^n(i)
200 IF op$ = "max" THEN temp = FN MAX(temp,n(i))
210 IF op$ = "min" THEN temp = FN MIN(temp,n(i))
220 IF op$ = "avg" THEN temp = temp+n(i)
230 IF op$ = "cat" THEN temp$ = temp$+STR$(n(i))
240 NEXT i
250 IF op$ = "avg" THEN temp = temp/cnt
260 IF op$ = "cat" THEN temp = VAL(STR$(n(1))+temp$)
270 cat = temp
280 END SUB
290 '
300 PRINT " +: ";cat(10,"+")
310 PRINT " -: ";cat(10,"-")
320 PRINT " *: ";cat(10,"*")
330 PRINT " /: ";cat(10,"/")
340 PRINT " ^: ";cat(10,"^")
350 PRINT "min: ";cat(10,"min")
360 PRINT "max: ";cat(10,"max")
370 PRINT "avg: ";cat(10,"avg")
380 PRINT "cat: ";cat(10,"cat")
390 END</syntaxhighlight>
 
==={{header|QBasic}}===
{{works with|QBasic|1.1}}
{{trans|Run BASIC}}
<syntaxhighlight lang="qbasic">DIM SHARED n(10)
FOR i = 1 TO 10: n(i) = i: NEXT i
 
FUNCTION FNMIN (a, b)
IF (a < b) THEN FNMIN = a ELSE FNMIN = b
END FUNCTION
FUNCTION FNMAX (a, b)
IF (a < b) THEN FNMAX = b ELSE FNMAX = a
END FUNCTION
 
FUNCTION cat# (cont, op$)
temp = n(1)
FOR i = 2 TO cont
IF op$ = "+" THEN temp = temp + n(i)
IF op$ = "-" THEN temp = temp - n(i)
IF op$ = "*" THEN temp = temp * n(i)
IF op$ = "/" THEN temp = temp / n(i)
IF op$ = "^" THEN temp = temp ^ n(i)
IF op$ = "max" THEN temp = FNMAX(temp, n(i))
IF op$ = "min" THEN temp = FNMIN(temp, n(i))
IF op$ = "avg" THEN temp = temp + n(i)
NEXT i
IF op$ = "avg" THEN temp = temp / cont
cat = temp
END FUNCTION
 
PRINT " +: "; " "; cat(10, "+")
PRINT " -: "; " "; cat(10, "-")
PRINT " *: "; " "; cat(10, "*")
PRINT " /: "; " "; cat(10, "/")
PRINT " ^: "; " "; cat(10, "^")
PRINT "min: "; " "; cat(10, "min")
PRINT "max: "; " "; cat(10, "max")
PRINT "avg: "; " "; cat(10, "avg")</syntaxhighlight>
 
==={{header|True BASIC}}===
<syntaxhighlight lang="qbasic">SHARE n(10)
FOR i = 1 to 10
LET n(i) = i
NEXT i
 
FUNCTION fnmin(a,b)
IF (a < b) then LET fnmin = a else LET fnmin = b
END FUNCTION
FUNCTION fnmax(a,b)
IF (a < b) then LET fnmax = b else LET fnmax = a
END FUNCTION
 
FUNCTION cat(cont, op$)
LET temp = n(1)
LET temp$ = ""
FOR i = 2 TO cont
IF op$ = "+" then LET temp = temp+n(i)
IF op$ = "-" then LET temp = temp-n(i)
IF op$ = "*" then LET temp = temp*n(i)
IF op$ = "/" then LET temp = temp/n(i)
IF op$ = "^" then LET temp = temp^n(i)
IF op$ = "max" then LET temp = fnmax(temp,n(i))
IF op$ = "min" then LET temp = fnmin(temp,n(i))
IF op$ = "avg" then LET temp = temp+n(i)
IF op$ = "cat" then LET temp$ = temp$ & str$(n(i))
NEXT i
IF op$ = "avg" then
LET temp = temp / cont
END IF
IF op$ = "cat" then
LET t$ = str$(n(1)) & temp$
LET temp = VAL(t$)
END IF
LET cat = temp
END FUNCTION
 
PRINT " +: "; " "; cat(10, "+")
PRINT " -: "; " "; cat(10, "-")
PRINT " *: "; " "; cat(10, "*")
PRINT " /: "; " "; cat(10, "/")
PRINT " ^: "; " "; cat(10, "^")
PRINT "min: "; " "; cat(10, "min")
PRINT "max: "; " "; cat(10, "max")
PRINT "avg: "; " "; cat(10, "avg")
PRINT "cat: "; " "; cat(10, "cat")
END</syntaxhighlight>
 
==={{header|Yabasic}}===
{{trans|Run BASIC}}
<syntaxhighlight lang="freebasic">dim n(10)
for i = 1 to 10 : n(i) = i : next i
print " +: ", " ", cat(10, "+")
print " -: ", " ", cat(10, "-")
print " *: ", " ", cat(10, "*")
print " /: ", " ", cat(10, "/")
print " ^: ", " ", cat(10, "^")
print "min: ", " ", cat(10, "min")
print "max: ", " ", cat(10, "max")
print "avg: ", " ", cat(10, "avg")
end
sub cat(cont,op$)
cat = n(1)
for i = 2 to cont
if op$ = "+" cat = cat + n(i)
if op$ = "-" cat = cat - n(i)
if op$ = "*" cat = cat * n(i)
if op$ = "/" cat = cat / n(i)
if op$ = "^" cat = cat ^ n(i)
if op$ = "max" cat = max(cat,n(i))
if op$ = "min" cat = min(cat,n(i))
if op$ = "avg" cat = cat + n(i)
next i
if op$ = "avg" cat = cat / cont
return cat
end sub</syntaxhighlight>
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang="bbcbasic">
DIM a(4)
a() = 1, 2, 3, 4, 5
Line 193 ⟶ 588:
NEXT
= tmp
</syntaxhighlight>
</lang>
 
{{out}}
Line 199 ⟶ 594:
-13
120</pre>
=={{header|BCPL}}==
<syntaxhighlight lang="bcpl">get "libhdr"
 
let reduce(f, v, len, seed) =
len = 0 -> seed,
reduce(f, v+1, len-1, f(!v, seed))
 
let start() be
$( let add(x, y) = x+y
let mul(x, y) = x*y
let nums = table 1,2,3,4,5,6,7
writef("%N*N", reduce(add, nums, 7, 0))
writef("%N*N", reduce(mul, nums, 7, 1))
$)</syntaxhighlight>
{{out}}
<pre>28
5040</pre>
 
=={{header|Binary Lambda Calculus}}==
 
A minimal size (right) fold in lambda calculus is <code>fold = \f\z (let go = \l.l(\h\t\z.f h (go t))z in go)</code> which corresponds to the 69-bit BLC program
 
<pre>000001000110100000010110000000010111111110111001011111101111101101110</pre>
 
=={{header|BQN}}==
 
BQN has two different primitives for catamorphism:
<ul>
<li>Fold(<code>´</code>): Works on lists only.</li>
<li>Insert(<code>˝</code>): Works on arrays with higher rank.</li>
</ul>
 
Both of these primitives take a dyadic function, and an optional initial element.
 
<pre>•Show +´ 30‿1‿20‿2‿10
•Show +˝ 30‿1‿20‿2‿10
•Show tab ← (2+↕5) |⌜ 9+↕3
•Show +˝ tab</pre>
<pre>63
┌·
· 63
┌─
╵ 1 0 1
0 1 2
1 2 3
4 0 1
3 4 5
⟨ 9 7 12 ⟩</pre>
=={{header|Bracmat}}==
<syntaxhighlight lang="bracmat">( ( fold
= f xs init first rest
. !arg:(?f.?xs.?init)
& ( !xs:&!init
| !xs:%?first ?rest
& !f$(!first.fold$(!f.!rest.!init))
)
)
& out
$ ( fold
$ ( (=a b.!arg:(?a.?b)&!a+!b)
. 1 2 3 4 5
. 0
)
)
& (product=a b.!arg:(?a.?b)&!a*!b)
& out$(fold$(product.1 2 3 4 5.1))
);</syntaxhighlight>
Output:
<pre>15
120</pre>
=={{header|C}}==
<langsyntaxhighlight Clang="c">#include <stdio.h>
 
typedef int (*intFn)(int, int);
Line 224 ⟶ 692:
printf("%d\n", reduce(mul, 5, nums));
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 230 ⟶ 698:
-13
120</pre>
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">var nums = Enumerable.Range(1, 10);
 
int summation = nums.Aggregate((a, b) => a + b);
 
int product = nums.Aggregate((a, b) => a * b);
 
string concatenation = nums.Aggregate(String.Empty, (a, b) => a.ToString() + b.ToString());
 
Console.WriteLine("{0} {1} {2}", summation, product, concatenation);</syntaxhighlight>
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <numeric>
#include <functional>
Line 245 ⟶ 722:
std::cout << "nums_added: " << nums_added << std::endl;
std::cout << "nums_other: " << nums_other << std::endl;
}</langsyntaxhighlight>
 
{{out}}
Line 251 ⟶ 728:
<pre>nums_added: 15
nums_other: 30</pre>
 
=={{header|C sharp}}==
<lang csharp>var nums = Enumerable.Range(1, 10);
 
int summation = nums.Aggregate((a, b) => a + b);
 
int product = nums.Aggregate((a, b) => a * b);
 
string concatenation = nums.Aggregate(String.Empty, (a, b) => a.ToString() + b.ToString());
 
Console.WriteLine("{0} {1} {2}", summation, product, concatenation);</lang>
 
=={{header|Clojure}}==
For more detail, check Rich Hickey's [http://clojure.com/blog/2012/05/08/reducers-a-library-and-model-for-collection-processing.html blog post on Reducers].
 
<langsyntaxhighlight lang="clojure">; Basic usage
> (reduce * '(1 2 3 4 5))
120
Line 272 ⟶ 737:
> (reduce + 100 '(1 2 3 4 5))
115
</syntaxhighlight>
</lang>
=={{header|CLU}}==
<syntaxhighlight lang="clu">% Reduction.
% First type = sequence type (must support S$elements and yield R)
% Second type = right (input) datatype
% Third type = left (output) datatype
reduce = proc [S,R,L: type] (f: proctype (L,R) returns (L),
id: L,
seq: S)
returns (L)
where S has elements: itertype (S) yields (R)
 
for elem: R in S$elements(seq) do
id := f(id, elem)
end
return(id)
end reduce
 
% This is necessary to get rid of the exceptions
add = proc (a,b: int) returns (int) return (a+b) end add
mul = proc (a,b: int) returns (int) return (a*b) end mul
 
% Usage
start_up = proc ()
% abbreviation - reducing int->int->int function over an array[int]
int_reduce = reduce[array[int], int, int]
po: stream := stream$primary_output()
nums: array[int] := array[int]$[1,2,3,4,5,6,7,8,9,10]
% find the sum and the product using reduce
sum: int := int_reduce(add, 0, nums)
product: int := int_reduce(mul, 1, nums)
stream$putl(po, "The sum of [1..10] is: " || int$unparse(sum))
stream$putl(po, "The product of [1..10] is: " || int$unparse(product))
end start_up</syntaxhighlight>
{{out}}
<pre>The sum of [1..10] is: 55
The product of [1..10] is: 3628800</pre>
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">; Basic usage
> (reduce #'* '(1 2 3 4 5))
120
Line 292 ⟶ 795:
; Compare with
> (reduce #'expt '(2 3 4))
4096</langsyntaxhighlight>
 
=={{header|D}}==
<langsyntaxhighlight lang="d">void main() {
import std.stdio, std.algorithm, std.range, std.meta, std.numeric,
std.conv, std.typecons, std.typetuple;
 
auto list = iota(1, 11);
alias ops = TypeTupleAliasSeq!(q{a + b}, q{a * b}, min, max, gcd);
 
foreach (op; ops)
Line 307 ⟶ 809:
// std.algorithm.reduce supports multiple functions in parallel:
reduce!(ops[0], ops[3], text)(tuple(0, 0.0, ""), list).writeln;
}</langsyntaxhighlight>
{{out}}
<pre>"a + b": 55
Line 316 ⟶ 818:
Tuple!(int,double,string)(55, 10, "12345678910")</pre>
=={{header|DCL}}==
<langsyntaxhighlight DCLlang="dcl">$ list = "1,2,3,4,5"
$ call reduce list "+"
$ show symbol result
Line 341 ⟶ 843:
$ result == value
$ exit
$ endsubroutine</langsyntaxhighlight>
{{out}}
<pre>$ @catamorphism
Line 347 ⟶ 849:
RESULT == -5 Hex = FFFFFFFB Octal = 37777777773
RESULT == 120 Hex = 00000078 Octal = 00000000170</pre>
=={{header|Delphi}}==
 
See [https://rosettacode.org/wiki/Catamorphism#Pascal Pascal].
=={{header|Déjà Vu}}==
This is a foldl:
<langsyntaxhighlight lang="dejavu">reduce f lst init:
if lst:
f reduce @f lst init pop-from lst
Line 358 ⟶ 861:
!. reduce @+ [ 1 10 200 ] 4
!. reduce @- [ 1 10 200 ] 4
</syntaxhighlight>
</lang>
{{out}}
<pre>215
-207</pre>
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang="scheme">
;; rem : the foldX family always need an initial value
;; fold left a list
Line 384 ⟶ 886:
(scanl * 1 '( 1 2 3 4 5))
→ (1 1 2 6 24 120)
</syntaxhighlight>
</lang>
=={{header|Elena}}==
 
ELENA 5.0 :
<syntaxhighlight lang="elena">import system'collections;
import system'routines;
import extensions;
import extensions'text;
public program()
{
var numbers := new Range(1,10).summarize(new ArrayList());
var summary := numbers.accumulate(new Variable(0), (a,b => a + b));
var product := numbers.accumulate(new Variable(1), (a,b => a * b));
var concatenation := numbers.accumulate(new StringWriter(), (a,b => a.toPrintable() + b.toPrintable()));
console.printLine(summary," ",product," ",concatenation)
}</syntaxhighlight>
{{out}}
<pre>
55 362880 12345678910
</pre>
=={{header|Elixir}}==
<langsyntaxhighlight lang="elixir">iex(1)> Enum.reduce(1..10, fn i,acc -> i+acc end)
55
iex(2)> Enum.reduce(1..10, fn i,acc -> i*acc end)
3628800
iex(3)> Enum.reduce(10..-10, "", fn i,acc -> acc <> to_string(i) end)
"109876543210-1-2-3-4-5-6-7-8-9-10"</langsyntaxhighlight>
 
=={{header|Erlang}}==
{{trans|Haskell}}
 
<langsyntaxhighlight lang="erlang">
-module(catamorphism).
 
Line 414 ⟶ 937:
Nums),
{Summation, Product, Concatenation}.
</syntaxhighlight>
</lang>
 
Output:
Line 420 ⟶ 943:
{55,3628800,"12345678910"}
</pre>
=={{header|Excel}}==
===LAMBDA===
 
Excel provides a good number of standard catamorphisms like SUM, PRODUCT, LEN etc out of the box, but in recent builds of Excel we can write more general catamorphisms as LAMBDA expressions, and bind names to them in the WorkBook Name Manager.
 
Excel's compound data type is a non-empty array, for which we could write, for example, specialised column or row instances of fold, whether rightward or leftward.
 
Here is an example of binding the name FOLDLROW to a left fold over a row of Excel cells.
 
As an example of a binary operator to fold, with an accumulator, over a series of character values, we can define a custom:
 
'''updateBracketDepth(accumulator)(character)''' which:
 
# Increments the nesting depth given a "[" character
# reduces it given a "]" character
# leaves the nesting depth unchanged for any other character
# updates the accumulator no further if the nesting depth ever becomes negative.
 
 
or for a simple bracket count, we could just define a:
 
'''bracketCount(accumulator)(character)''' which:
 
# Increments the integer accumulator value on each "[" or "]"
# Leaves the accumulator unchanged for other characters.
 
 
(See [https://www.microsoft.com/en-us/research/blog/lambda-the-ultimatae-excel-worksheet-function/ LAMBDA: The ultimate Excel worksheet function])
 
{{Works with|Office 365 betas 2021}}
<syntaxhighlight lang="lisp">FOLDROW
=LAMBDA(op,
LAMBDA(a,
LAMBDA(xs,
LET(
b, op(a)(HEADROW(xs)),
 
IF(1 < COLUMNS(xs),
FOLDROW(op)(b)(
TAILROW(xs)
),
b
)
)
)
)
)
 
 
updatedBracketDepth
=LAMBDA(depth,
LAMBDA(c,
IF(0 <= depth,
IF("[" = c,
1 + depth,
IF("]" = c,
depth - 1,
depth
)
),
depth
)
)
)
 
 
bracketCount
=LAMBDA(a,
LAMBDA(c,
IF(ISNUMBER(FIND(c, "[]", 1)),
1 + a,
a
)
)
)
 
 
HEADROW
=LAMBDA(xs,
LET(REM, "The first item of each row in xs",
 
INDEX(
xs,
SEQUENCE(ROWS(xs)),
SEQUENCE(1, 1)
)
)
)
 
 
TAILROW
=LAMBDA(xs,
LET(REM,"The tail of each row in the grid",
n, COLUMNS(xs) - 1,
 
IF(0 < n,
INDEX(
xs,
SEQUENCE(ROWS(xs), 1, 1, 1),
SEQUENCE(1, n, 2, 1)
),
NA()
)
)
)
 
 
CHARSROW
=LAMBDA(s,
MID(s,
SEQUENCE(1, LEN(s), 1, 1),
1
)
)</syntaxhighlight>
 
{{Out}}
{| class="wikitable"
|-
|||style="text-align:right; font-family:serif; font-style:italic; font-size:120%;"|fx
! colspan="3" style="text-align:left; vertical-align: bottom; font-family:Arial, Helvetica, sans-serif !important;"|=FOLDROW( updatedBracketDepth )( 0 )( CHARSROW(C2) )
|- style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff;"
|
| A
| B
| C
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 1
|
| style="font-weight:bold" | Final bracket nesting depth
| style="font-weight:bold" | Sample string
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 2
|
| style="text-align:center; background-color:#cbcefb" | 0
| [simply bracketed]
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 3
|
| style="text-align:center" | 1
| [[ ]
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 4
|
| style="text-align:center" | -1
| [ ]]
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 5
|
| style="text-align:center" | 0
| [[[ [] ]]]
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 6
|
| style="text-align:center" | 0
| [ [[[ [] ]]] [[[ ]]] [[[ [] ]]] ]
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 7
|
| style="text-align:center" | 1
| [ [[[ [ ]]] [[[ ]]] [[[ [] ]]] ]
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 8
|
| style="text-align:center" | -1
| ][ [[[ [ ]]] [[[ ]]] [[[ [] ]]] ]
|}
 
Or for a simple count of bracket characters, ignoring other characters:
 
{| class="wikitable"
|-
|||style="text-align:right; font-family:serif; font-style:italic; font-size:120%;"|fx
! colspan="3" style="text-align:left; vertical-align: bottom; font-family:Arial, Helvetica, sans-serif !important;"|=FOLDROW( bracketCount )( 0 )( CHARSROW(C2) )
|- style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff;"
|
| A
| B
| C
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 1
|
| style="font-weight:bold" | Bracket character count
| style="font-weight:bold" | Sample string
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 2
|
| style="text-align:center; background-color:#cbcefb" | 2
| [simply bracketed]
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 3
|
| style="text-align:center" | 3
| [[ ]
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 4
|
| style="text-align:center" | 3
| [ ]]
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 5
|
| style="text-align:center" | 8
| [[[ [] ]]]
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 6
|
| style="text-align:center" | 24
| [ [[[ [] ]]] [[[ ]]] [[[ [] ]]] ]
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 7
|
| style="text-align:center" | 23
| [ [[[ [ ]]] [[[ ]]] [[[ [] ]]] ]
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 8
|
| style="text-align:center" | 24
| ][ [[[ [ ]]] [[[ ]]] [[[ [] ]]] ]
|}
=={{header|F_Sharp|F#}}==
<p>In the REPL:</p>
<pre>
> let nums = [1 .. 10];;
 
val nums : int list = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
 
> let summation = List.fold (+) 0 nums;;
 
val summation : int = 55
 
> let product = List.fold (*) 1 nums;;
 
val product : int = 3628800
 
> let concatenation = List.foldBack (fun x y -> x + y) (List.map (fun i -> i.ToString()) nums) "";;
 
val concatenation : string = "12345678910"
</pre>
=={{header|Factor}}==
 
<syntaxhighlight lang="factor">{ 1 2 4 6 10 } 0 [ + ] reduce .</syntaxhighlight>
{{out}}
<pre>
23
</pre>
=={{header|Forth}}==
Forth has three traditions for iterating over the members of a data
Line 451 ⟶ 1,218:
Some helper words for these examples:
 
<langsyntaxhighlight lang="forth">: lowercase? ( c -- f )
[char] a [ char z 1+ ] literal within ;
 
: char-upcase ( c -- C )
dup lowercase? if bl xor then ;</langsyntaxhighlight>
 
Using normal looping words:
 
<langsyntaxhighlight lang="forth">: string-at ( c-addr u +n -- c )
nip + c@ ;
: string-at! ( c-addr u +n c -- )
Line 477 ⟶ 1,244:
0 -rot dup 0 ?do
2dup i string-at lowercase? if rot 1+ -rot then
loop 2drop ;</langsyntaxhighlight>
 
Briefly, a variation:
 
<langsyntaxhighlight lang="forth">: next-char ( a +n -- a' n' c -1 ) ( a 0 -- 0 )
dup if 2dup 1 /string 2swap drop c@ true
else 2drop 0 then ;
Line 488 ⟶ 1,255:
begin next-char while
dup lowercase? if emit else drop then
repeat ;</langsyntaxhighlight>
 
Using dedicated looping words:
 
<langsyntaxhighlight lang="forth">: each-char[ ( c-addr u -- )
postpone BOUNDS postpone ?DO
postpone I postpone C@ ; immediate
Line 508 ⟶ 1,275:
 
: count-lowercase ( c-addr u -- n )
0 -rot each-char[ lowercase? if 1+ then ]each-char ;</langsyntaxhighlight>
 
Using higher-order words:
 
<langsyntaxhighlight lang="forth">: each-char ( c-addr u xt -- )
{: xt :} bounds ?do
i c@ xt execute
Line 528 ⟶ 1,295:
 
: count-lowercase ( c-addr u -- n )
0 -rot [: lowercase? if 1+ then ;] each-char ;</langsyntaxhighlight>
 
In these examples COUNT-LOWERCASE updates an accumulator, UPCASE
(mostly) modifies the string in-place, and TYPE-LOWERCASE performs
side-effects and returns nothing to the higher-order word.
=={{header|Fortran}}==
If Fortran were to offer the ability to pass a parameter "by name", as is used in [[Jensen's_Device#Fortran|Jensen's device]], then the code might be something like <syntaxhighlight lang="fortran"> SUBROUTINE FOLD(t,F,i,ist,lst)
INTEGER t
BYNAME F
DO i = ist,lst
t = F
END DO
END SUBROUTINE FOLD !Result in temp.
 
temp = a(1); CALL FOLD(temp,temp*a(i),i,2,N)</syntaxhighlight>
Here, the function manifests as the expression that is the second parameter of subroutine FOLD, and the "by name" protocol for parameter F means that within the subroutine whenever there is a reference to F, its value is evaluated afresh in the caller's environment using the current values of ''temp'' and ''i'' as modified by the subroutine - they being passed by reference so that changes within the subroutine affect the originals. An evaluation for a different function requires merely another statement with a different expression.
 
Fortran however does not provide such a facility. Any parameter that is an expression is evaluated once in the caller's environment, the result placed in temporary storage, and the address of that storage location is passed to the subroutine. Repeated references to that parameter will elicit the same value. But there is special provision for passing a function to a routine, involving the special word EXTERNAL. For every different function in mind, one must diligently supply a name, and work through the overhead of declaring each such function. There is an additional word, INTRINSIC, for use when an intrinsic function (such as SIN) is to be passed as such a parameter since it will appear as its name only, and with the absence of the (...) that would be used for the function's parameters when in an arithmetic expression, it would otherwise be taken as being the name of an ordinary variable.
 
Here is such an arrangement, in the style of F77 though somewhat affected by F90 in that the END statement names the routine being ended. Similarly, to abate petty complaints about the types of the functions being undeclared, explicit types are specified, though unselecting the compiler diagnostic for that would match the habits of earlier compilers. Also in F90 is the MODULE protocol which involves rather more organised checking of types and additional facilities for arrays [[Array_length#Fortran|so that N need not be passed]] because secret additional parameters do so.
 
However, only programmer diligence in devising functions with the correct type of result and the correct type and number of parameters will evade mishaps. Note that the EXTERNAL statement does not specify the number or type of parameters. If the function is invoked multiple times within a subroutine, the compiler may check for consistency. This may cause trouble when [[Leonardo_numbers#Fortran|some parameters are optional]] so that different invocations do not match.
 
The function's name is used as a working variable within the function (as well as it holding the function's value on exit) so that the expression <code>F(IFOLD,A(I))</code> is ''not'' a recursive invocation of function <code>IFOLD</code> because there are no (parameters) appended to the function's name. Earlier compilers did not allow such usage so that a separate working variable would be required. <syntaxhighlight lang="fortran"> INTEGER FUNCTION IFOLD(F,A,N) !"Catamorphism"...
INTEGER F !We're working only with integers.
EXTERNAL F !This is a function, not an array.
INTEGER A(*) !An 1-D array, of unspecified size.
INTEGER N !The number of elements.
INTEGER I !A stepper.
IFOLD = 0 !A default value.
IF (N.LE.0) RETURN !Dodge silly invocations.
IFOLD = A(1) !The function is to have two arguments.
IF (N.EQ.1) RETURN !So, if there is only one element, silly.
DO I = 2,N !Otherwise, stutter along the array.
IFOLD = F(IFOLD,A(I)) !Applying the function.
END DO !On to the next element.
END FUNCTION IFOLD!Thus, F(A(1),A(2)), or F(F(A(1),A(2)),A(3)), or F(F(F(A(1),A(2)),A(3)),A(4)), etc.
 
INTEGER FUNCTION IADD(I,J)
INTEGER I,J
IADD = I + J
END FUNCTION IADD
 
INTEGER FUNCTION IMUL(I,J)
INTEGER I,J
IMUL = I*J
END FUNCTION IMUL
 
INTEGER FUNCTION IDIV(I,J)
INTEGER I,J
IDIV = I/J
END FUNCTION IDIV
 
INTEGER FUNCTION IVID(I,J)
INTEGER I,J
IVID = J/I
END FUNCTION IVID
 
PROGRAM POKE
INTEGER ENUFF
PARAMETER (ENUFF = 6)
INTEGER A(ENUFF)
PARAMETER (A = (/1,2,3,4,5,6/))
INTEGER MSG
EXTERNAL IADD,IMUL,IDIV,IVID !Warn that these are the names of functions.
 
MSG = 6 !Standard output.
WRITE (MSG,1) ENUFF,A
1 FORMAT ('To apply a function in the "catamorphic" style ',
1 "to the ",I0," values ",/,(20I3))
 
WRITE (MSG,*) "Iadd",IFOLD(IADD,A,ENUFF)
WRITE (MSG,*) "Imul",IFOLD(IMUL,A,ENUFF)
WRITE (MSG,*) "Idiv",IFOLD(IDIV,A,ENUFF)
WRITE (MSG,*) "Ivid",IFOLD(IVID,A,ENUFF)
END PROGRAM POKE
</syntaxhighlight>
Output:
<pre>
To apply a function in the "catamorphic" style to the 6 values
1 2 3 4 5 6
Iadd 21
Imul 720
Idiv 0
Ivid 6
</pre>
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
Type IntFunc As Function(As Integer, As Integer) As Integer
Function reduce(a() As Integer, f As IntFunc) As Integer
'' if array is empty or function pointer is null, return 0 say
If UBound(a) = -1 OrElse f = 0 Then Return 0
Dim result As Integer = a(LBound(a))
For i As Integer = LBound(a) + 1 To UBound(a)
result = f(result, a(i))
Next
Return result
End Function
 
Function add(x As Integer, y As Integer) As Integer
Return x + y
End Function
 
Function subtract(x As Integer, y As Integer) As Integer
Return x - y
End Function
 
Function multiply(x As Integer, y As Integer) As Integer
Return x * y
End Function
 
Function max(x As Integer, y As Integer) As Integer
Return IIf(x > y, x, y)
End Function
 
Function min(x As Integer, y As Integer) As Integer
Return IIf(x < y, x, y)
End Function
 
Dim a(4) As Integer = {1, 2, 3, 4, 5}
Print "Sum is :"; reduce(a(), @add)
Print "Difference is :"; reduce(a(), @subtract)
Print "Product is :"; reduce(a(), @multiply)
Print "Maximum is :"; reduce(a(), @max)
Print "Minimum is :"; reduce(a(), @min)
Print "No op is :"; reduce(a(), 0)
Print
Print "Press any key to quit"
Sleep
</syntaxhighlight>
 
{{out}}
<pre>
Sum is : 15
Difference is :-13
Product is : 120
Maximum is : 5
Minimum is : 1
No op is : 0
</pre>
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 559 ⟶ 1,462:
}
return r
}</langsyntaxhighlight>
{{out}}
<pre>
Line 566 ⟶ 1,469:
120
</pre>
 
=={{header|Groovy}}==
Groovy provides an "inject" method for all aggregate classes that performs a classic tail-recursive reduction, driven by a closure argument. The result of each iteration (closure invocation) is used as the accumulated valued for the next iteration. If a first argument is provided as well as a second closure argument, that first argument is used as a seed accumulator for the first iteration. Otherwise, the first element of the aggregate is used as the seed accumulator, with reduction iteration proceeding across elements 2 through n.
<langsyntaxhighlight lang="groovy">def vector1 = [1,2,3,4,5,6,7]
def vector2 = [7,6,5,4,3,2,1]
def map1 = [a:1, b:2, c:3, d:4]
Line 581 ⟶ 1,483:
println (map1.inject { Map.Entry accEntry, Map.Entry entry -> // some sort of weird map-based reduction
[(accEntry.key + entry.key):accEntry.value + entry.value ].entrySet().toList().pop()
})</langsyntaxhighlight>
 
{{out}}
Line 590 ⟶ 1,492:
84
abcd=10</pre>
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">numsmain =:: IO [1..10]()
main =
putStrLn . unlines $
[ show . foldr (+) 0 -- sum
, show . foldr (*) 1 -- product
, foldr ((++) . show) "" -- concatenation
] <*>
[[1 .. 10]]</syntaxhighlight>
{{Out}}
<pre>55
3628800
12345678910</pre>
 
and the generality of folds is such that if we replace all three of these (function, identity) combinations ((+), 0), ((*), 1) ((++), "") with the Monoid operation '''mappend''' (<>) and identity '''mempty''', we can still obtain the same results:
summation = foldl (+) 0 nums
product = foldl (*) 1 nums
concatenation = foldr (\num s -> show num ++ s) "" nums</lang>
 
<syntaxhighlight lang="haskell">import Data.Monoid
There is are also ''foldl1'' and ''foldr1'' available that implicitly take first element as starting value. However they are not safe as they fail on empty lists.
 
main :: IO ()
''Prelude'' folds work only on lists, module ''Data.Foldable'' a typeclass for more general fold - interface remains the same.
main =
let xs = [1 .. 10]
in (putStrLn . unlines)
[ (show . getSum . foldr (<>) mempty) (Sum <$> xs)
, (show . getProduct . foldr (<>) mempty) (Product <$> xs)
, (show . foldr (<>) mempty) (show <$> xs)
, (show . foldr (<>) mempty) (words
"Love is one damned thing after each other")
]</syntaxhighlight>
{{Out}}
<pre>55
3628800
"12345678910"
"Loveisonedamnedthingaftereachother"</pre>
 
Also available are ''foldl1'' and ''foldr1'' which implicitly take first element as starting value. However they are not safe as they fail on empty lists.
 
''Prelude'' folds work only on lists, module ''Data.Foldable'' a typeclass for more general fold - interface remains the same.
=={{header|Icon}} and {{header|Unicon}}==
 
Works in both languages:
<langsyntaxhighlight lang="unicon">procedure main(A)
write(A[1],": ",curry(A[1],A[2:0]))
end
Line 613 ⟶ 1,540:
every r := f(r, !A[2:0])
return r
end</langsyntaxhighlight>
 
Sample runs:
Line 626 ⟶ 1,553:
||: 314159
</pre>
 
=={{header|J}}==
'''Solution''':<syntaxhighlight lang ="j"> /</langsyntaxhighlight>
'''Example''':<langsyntaxhighlight lang="j"> +/ 1 2 3 4 5
15
*/ 1 2 3 4 5
120
!/ 1 2 3 4 5 NB. "n ! k" is "n choose k"
45</langsyntaxhighlight>
Insert * into 1 2 3 4 5
 
becomes
1 * 2 * 3 * 4 * 5
evaluated right to left<syntaxhighlight lang="j">
1 * 2 * 3 * 20
1 * 2 * 60
1 * 120
120
</syntaxhighlight>
What are the implications for -/ ?
For %/ ?
=={{header|Java}}==
{{works with|Java|8}}
<langsyntaxhighlight lang="java">import java.util.stream.Stream;
 
public class ReduceTask {
Line 646 ⟶ 1,582:
System.out.println(Stream.of(1, 2, 3, 4, 5).reduce(1, (a, b) -> a * b));
}
}</langsyntaxhighlight>
 
{{out}}
<pre>15
120</pre>
 
=={{header|JavaScript}}==
 
<lang javascript>var nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
===ES5===
 
<syntaxhighlight lang="javascript">var nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 
function add(a, b) {
Line 669 ⟶ 1,607:
var concatenation = nums.reduce(add, "");
 
console.log(summation, product, concatenation);</langsyntaxhighlight>
 
 
Note that the JavaScript Array methods include a right fold ( '''.reduceRight()''' ) as well as a left fold:
 
<langsyntaxhighlight JavaScriptlang="javascript">(function (xs) {
'use strict';
 
Line 694 ⟶ 1,632:
});
 
})([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);</langsyntaxhighlight>
 
{{Out}}
Line 701 ⟶ 1,639:
"18 16 14 12 10 8 6 4 2 0 "]</pre>
 
===ES6===
 
<syntaxhighlight lang="javascript">var nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 
console.log(nums.reduce((a, b) => a + b, 0)); // sum of 1..10
console.log(nums.reduce((a, b) => a * b, 1)); // product of 1..10
console.log(nums.reduce((a, b) => a + b, '')); // concatenation of 1..10</syntaxhighlight>
=={{header|jq}}==
jq has an unusual and unusually powerful "reduce" control structure. A full description is beyond the scope of this short article, but an important point is that "reduce" is stream-oriented. Reduction of arrays is however trivially achieved using the ".[]" filter for converting an array to a stream of its values.
Line 715 ⟶ 1,660:
 
The "reduce" operator is typically used within a map/reduce framework, but the implicit state variable can be any JSON entity, and so "reduce" is also a general-purpose iterative control structure, the only limitation being that it does not have the equivalent of "break". For that, the "foreach" control structure in recent versions of jq can be used.
 
=={{header|Julia}}==
{{Works with|Julia 1.2}}
<lang Julia>for op in [+, -, *] println(reduce(op, 1:5)) end</lang>
<syntaxhighlight lang="julia">println([reduce(op, 1:5) for op in [+, -, *]])
println([foldl(op, 1:5) for op in [+, -, *]])
println([foldr(op, 1:5) for op in [+, -, *]])</syntaxhighlight>
{{out}}
<pre>[15, -13, 120]
[15, -13, 120]
[15, 3, 120]</pre>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">fun main(args: Array<String>) {
val a = intArrayOf(1, 2, 3, 4, 5)
println("Array : ${a.joinToString(", ")}")
println("Sum : ${a.reduce { x, y -> x + y }}")
println("Difference : ${a.reduce { x, y -> x - y }}")
println("Product : ${a.reduce { x, y -> x * y }}")
println("Minimum : ${a.reduce { x, y -> if (x < y) x else y }}")
println("Maximum : ${a.reduce { x, y -> if (x > y) x else y }}")
}</syntaxhighlight>
 
{{out}}
<pre>15
Array : 1, 2, 3, 4, 5
-13
Sum : 15
120</pre>
Difference : -13
Product : 120
Minimum : 1
Maximum : 5
</pre>
 
=={{header|Lambdatalk}}==
<syntaxhighlight lang="scheme">
{def nums 1 2 3 4 5}
-> nums
{S.reduce {lambda {:a :b} {+ :a :b}} {nums}}
-> 15
{S.reduce {lambda {:a :b} {- :a :b}} {nums}}
-> -13
{S.reduce {lambda {:a :b} {* :a :b}} {nums}}
-> 120
{S.reduce min {nums}}
-> 1
{S.reduce max {nums}}
-> 5
</syntaxhighlight>
 
=={{header|Logtalk}}==
The Logtalk standard library provides implementations of common meta-predicates such as fold left. The example that follow uses Logtalk's native support for lambda expressions to avoid the need for auxiliary predicates.
<langsyntaxhighlight lang="logtalk">
:- object(folding_examples).
 
Line 741 ⟶ 1,724:
 
:- end_object.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 751 ⟶ 1,734:
yes
</pre>
 
=={{header|LOLCODE}}==
 
{{trans|C}}
 
<langsyntaxhighlight LOLCODElang="lolcode">HAI 1.3
 
HOW IZ I reducin YR array AN YR size AN YR fn
Line 782 ⟶ 1,764:
VISIBLE I IZ reducin YR array AN YR 5 AN YR mul MKAY
 
KTHXBYE</langsyntaxhighlight>
 
{{out}}
Line 788 ⟶ 1,770:
-13
120</pre>
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">
<lang Lua>
table.unpack = table.unpack or unpack -- 5.1 compatibility
local nums = {1,2,3,4,5,6,7,8,9}
Line 821 ⟶ 1,802:
print("cat {1..9}: ",reduce(cat,table.unpack(nums)))
 
</syntaxhighlight>
</lang>
 
{{out}}
Line 828 ⟶ 1,809:
5! : 120
cat {1..9}: 123456789
</pre>
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Module CheckIt {
Function Reduce (a, f) {
if len(a)=0 then Error "Nothing to reduce"
if len(a)=1 then =Array(a) : Exit
k=each(a, 2, -1)
m=Array(a)
While k {
m=f(m, array(k))
}
=m
}
a=(1, 2, 3, 4, 5)
Print "Array", a
Print "Sum", Reduce(a, lambda (x,y)->x+y)
Print "Difference", Reduce(a, lambda (x,y)->x-y)
Print "Product", Reduce(a, lambda (x,y)->x*y)
Print "Minimum", Reduce(a, lambda (x,y)->if(x<y->x, y))
Print "Maximum", Reduce(a, lambda (x,y)->if(x>y->x, y))
}
CheckIt
</syntaxhighlight>
{{out}}
<pre>
Array 1 2 3 4 5
Sum 15
Difference -13
Product 120
Minimum 1
Maximum 5
</pre>
 
=={{header|Maple}}==
The left fold operator in Maple is foldl, and foldr is the right fold operator.
<langsyntaxhighlight Maplelang="maple">> nums := seq( 1 .. 10 );
nums := 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
 
Line 839 ⟶ 1,852:
 
> foldr( `*`, 1, nums ); # compute product using foldr
3628800</langsyntaxhighlight>
Compute the horner form of a (sorted) polynomial:
<langsyntaxhighlight Maplelang="maple">> foldl( (a,b) ->a*T+b, op(map2(op,1,[op( 72*T^5+37*T^4-23*T^3+87*T^2+44*T+29 )])));
((((72 T + 37) T - 23) T + 87) T + 44) T + 29</langsyntaxhighlight>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight lang="mathematica">Fold[f, x, {a, b, c, d}]</langsyntaxhighlight>
{{Out}}
<pre>f[f[f[f[x, a], b], c], d]</pre>
 
=={{header|Maxima}}==
<langsyntaxhighlight lang="maxima">lreduce(f, [a, b, c, d], x0);
/* (%o1) f(f(f(f(x0, a), b), c), d) */</langsyntaxhighlight>
 
<langsyntaxhighlight lang="maxima">lreduce("+", [1, 2, 3, 4], 100);
/* (%o1) 110 */</langsyntaxhighlight>
=={{header|min}}==
{{works with|min|0.19.3}}
<syntaxhighlight lang="min">(1 2 3 4) 0 '+ reduce puts! ; sum
(1 2 3 4) 1 '* reduce puts! ; product</syntaxhighlight>
{{out}}
<pre>
10
24
</pre>
=={{header|Modula-2}}==
<syntaxhighlight lang="modula2">MODULE Catamorphism;
FROM InOut IMPORT WriteString, WriteCard, WriteLn;
 
(* Alas, there are no generic types. This function works for
CARDINAL only - you would have to copy it and change the types
to reduce functions of other types. *)
TYPE Reduction = PROCEDURE (CARDINAL, CARDINAL): CARDINAL;
PROCEDURE reduce(func: Reduction;
arr: ARRAY OF CARDINAL;
first: CARDINAL): CARDINAL;
VAR i: CARDINAL;
BEGIN
FOR i := 0 TO HIGH(arr) DO
first := func(first, arr[i]);
END;
RETURN first;
END reduce;
 
(* Demonstration *)
PROCEDURE add(a,b: CARDINAL): CARDINAL;
BEGIN RETURN a+b; END add;
PROCEDURE mul(a,b: CARDINAL): CARDINAL;
BEGIN RETURN a*b; END mul;
 
PROCEDURE Demonstration;
VAR a: ARRAY [1..5] OF CARDINAL;
i: CARDINAL;
BEGIN
FOR i := 1 TO 5 DO a[i] := i; END;
WriteString("Sum of [1..5]: ");
WriteCard(reduce(add, a, 0), 3);
WriteLn;
WriteString("Product of [1..5]: ");
WriteCard(reduce(mul, a, 1), 3);
WriteLn;
END Demonstration;
 
BEGIN Demonstration;
END Catamorphism.</syntaxhighlight>
{{out}}
<pre>Sum of [1..5]: 15
Product of [1..5]: 120</pre>
=={{header|Nemerle}}==
The <tt>Nemerle.Collections</tt> namespace defines <tt>FoldLeft</tt>, <tt>FoldRight</tt> and <tt>Fold</tt> (an alias for <tt>FoldLeft</tt>) on any sequence that implements the <tt>IEnumerable[T]</tt> interface.
<langsyntaxhighlight Nemerlelang="nemerle">def seq = [1, 4, 6, 3, 7];
def sum = seq.Fold(0, _ + _); // Fold takes an initial value and a function, here the + operator</langsyntaxhighlight>
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import sequtils
 
block:
Line 870 ⟶ 1,932:
substraction = foldl(numbers, a - b)
multiplication = foldl(numbers, a * b)
words = @["nim", "rod", "is", "cool"]
concatenation = foldl(words, a & b)
 
Line 879 ⟶ 1,941:
substraction = foldr(numbers, a - b)
multiplication = foldr(numbers, a * b)
words = @["nim", "rod", "is", "cool"]
concatenation = foldr(words, a & b)</langsyntaxhighlight>
 
=={{header|Oberon-2}}==
{{Works with| oo2c Version 2}}
<langsyntaxhighlight lang="oberon2">
MODULE Catamorphism;
IMPORT
Line 957 ⟶ 2,018:
END
END Catamorphism.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 964 ⟶ 2,025:
-14400
</pre>
=={{header|Objeck}}==
<syntaxhighlight lang="objeck">
use Collection;
 
class Reducer {
function : Main(args : String[]) ~ Nil {
values := IntVector->New([1, 2, 3, 4, 5]);
values->Reduce(Add(Int, Int) ~ Int)->PrintLine();
values->Reduce(Mul(Int, Int) ~ Int)->PrintLine();
}
 
function : Add(a : Int, b : Int) ~ Int {
return a + b;
}
function : Mul(a : Int, b : Int) ~ Int {
return a * b;
}
}</syntaxhighlight>
Output
<pre>
15
120
</pre>
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml"># let nums = [1;2;3;4;5;6;7;8;9;10];;
val nums : int list = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
# let sum = List.fold_left (+) 0 nums;;
val sum : int = 55
# let product = List.fold_left ( * ) 1 nums;;
val product : int = 3628800</langsyntaxhighlight>
 
=={{header|Oforth}}==
reduce is already defined into Collection class :
 
<langsyntaxhighlight Oforthlang="oforth">[ 1, 2, 3, 4, 5 ] reduce(#max)
[ "abc", "def", "gfi" ] reduce(#+)</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">reduce(f, v)={
my(t=v[1]);
for(i=2,#v,t=f(t,v[i]));
t
};
reduce((a,b)->a+b, [1,2,3,4,5,6,7,8,9,10])</langsyntaxhighlight>
 
{{works with|PARI/GP|2.8.1+}}
<langsyntaxhighlight lang="parigp">fold((a,b)->a+b, [1..10])</langsyntaxhighlight>
=={{header|Pascal}}==
{{works with|Free Pascal}}
Should work with many pascal dialects
<langsyntaxhighlight lang="pascal">program reducereduceApp;
 
type
Line 1,044 ⟶ 2,126:
writeln(reduce(@sub,ma));
writeln(reduce(@mul,ma));
END.</langsyntaxhighlight>
output
<pre>-5,-4,-3,-2,-1,1,1,2,3,4,5
Line 1,050 ⟶ 2,132:
-11
-1440</pre>
 
=={{header|Perl}}==
Perl's reduce function is in a standard package.
<langsyntaxhighlight lang="perl">use List::Util 'reduce';
 
# note the use of the odd $a and $b globals
Line 1,060 ⟶ 2,141:
# first argument is really an anon function; you could also do this:
sub func { $b & 1 ? "$a $b" : "$b $a" }
print +(reduce \&func, 1 .. 10), "\n"</langsyntaxhighlight>
=={{header|Phix}}==
 
=={{headertrans|Perl 6C}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
{{works with|Rakudo|2015.12}}
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
Any associative infix operator, either built-in or user-defined, may be turned into a reduce operator by putting it into square brackets (known as "the reduce metaoperator") and using it as a list operator. The operations will work left-to-right or right-to-left automatically depending on the natural associativity of the base operator.
<span style="color: #008080;">function</span> <span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">b</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<lang perl6>my @list = 1..10;
<span style="color: #008080;">function</span> <span style="color: #000000;">sub</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">b</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
say [+] @list;
<span style="color: #008080;">function</span> <span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">b</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
say [*] @list;
say [~] @list;
<span style="color: #008080;">function</span> <span style="color: #000000;">reduce</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
say [min] @list;
<span style="color: #004080;">object</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
say [max] @list;
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
say [lcm] @list;</lang>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">reduce</span><span style="color: #0000FF;">(</span><span style="color: #000000;">add</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">))</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">reduce</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sub</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">))</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">reduce</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">))</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>55
15
3628800
-13
12345678910
120
1
</pre>
10
=={{header|Phixmonti}}==
2520</pre>
<syntaxhighlight lang="phixmonti">include ..\Utilitys.pmt
In addition to the reduce metaoperator, a general higher-order function, <tt>reduce</tt>, can apply any appropriate function. Reproducing the above in this form, using the function names of those operators, we have:
 
<lang perl6>say reduce &infix:<+>, @list;
def add + enddef
say reduce &infix:<*>, @list;
def sub - enddef
say reduce &infix:<~>, @list;
def mul * enddef
say reduce &infix:<min>, @list;
 
say reduce &infix:<max>, @list;
saydef reduce &infix:<lcm>, @list;</lang>ps
1 get
swap len 2 swap 2 tolist for
get rot swap tps exec swap
endfor
ps> drop
swap
enddef
 
 
( 1 2 3 4 5 )
getid add reduce ?
getid sub reduce ?
getid mul reduce ?</syntaxhighlight>
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de reduce ("Fun" "Lst")
(let "A" (car "Lst")
(for "N" (cdr "Lst")
Line 1,098 ⟶ 2,200:
(reduce * (1 2 3 4 5)) )
(bye)</langsyntaxhighlight>
=={{header|PowerShell}}==
 
'Filter' is a more common sequence function in PowerShell than 'reduce' or 'map', but here is one way to accomplish 'reduce':
<syntaxhighlight lang="powershell">
1..5 | ForEach-Object -Begin {$result = 0} -Process {$result += $_} -End {$result}
</syntaxhighlight>
{{Out}}
<pre>
15
</pre>
=={{header|Prolog}}==
SWI-Prolog has native foldl in version 6.3.1<br>
Module lambda was written by '''Ulrich Neumerkel''' and can be found there http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl
<lang Prolog>:- use_module(library(lambda)).
 
===Using <code>foldl</code> from <code>library(apply)</code> and Lambda-Expressions from <code>library(lambda)</code>===
% foldl is now a predicate of SWI-Prolog 6.3.1
 
%
* SWI-Prolog's [https://www.swi-prolog.org/pldoc/man?section=apply library(apply)] provides a [https://www.swi-prolog.org/pldoc/doc_for?object=foldl/4 `foldl/4`] (the source code of which can be seen [https://www.swi-prolog.org/pldoc/doc/_SWI_/library/apply.pl?show=src#foldl/4 here]).
* '''Ulrich Neumerkel''' wrote `library(lambda)` which can be found [http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl here]. (However, SWI-Prolog's Lambda Expressions are by default based on Paulo Moura's [https://www.swi-prolog.org/search?for=yall library(yall)])
 
<syntaxhighlight lang="prolog">:- use_module(library(lambda)).
 
catamorphism :-
numlist(1,10,L),
Line 1,116 ⟶ 2,228:
foldl(\XC^YC^ZC^(string_to_atom(XS, XC),string_concat(YC,XS,ZC)),
L, LV, Concat),
format('Concat of ~w is ~w~n', [L, Concat]).</langsyntaxhighlight>
{{out}}
<pre> ?- catamorphism.
Line 1,125 ⟶ 2,237:
</pre>
 
===Bare Prolog===
 
This is based on SWI Prolog 8 and has the following specificities:
 
* The consbox functor is <code>[|]</code> instead of <code>.</code>
* The list is terminated by the special atomic thing <code>[]</code> (the empty list)
 
<syntaxhighlight lang="prolog">
% List to be folded:
%
% +---+---+---+---[] <-- list backbone/spine, composed of nodes, terminating in the empty list
% | | | |
% a b c d <-- list items/entries/elements/members
%
</syntaxhighlight>
 
====linear <code>foldl</code>====
 
<syntaxhighlight lang="prolog">
% Computes "Out" as:
%
% starter value -->--f-->--f-->--f-->--f-->-- Out
% | | | |
% a b c d
 
 
foldl(Foldy,[Item|Items],Acc,Result) :- % case of nonempty list
!, % GREEN CUT for determinism
call(Foldy,Item,Acc,AccNext), % call Foldy(Item,Acc,AccNext)
foldl(Foldy,Items,AccNext,Result). % then recurse (open to tail call optimization)
 
foldl(_,[],Acc,Result) :- % case of empty list
Acc=Result. % unification not in head for clarity
</syntaxhighlight>
 
====linear <code>foldr</code>====
 
<syntaxhighlight lang="prolog">
% Computes "Out" as:
%
% Out --<--f--<--f--<--f--<--f--<-- starter value
% | | | |
% a b c d
 
foldr(Foldy,[Item|Items],Starter,AccUp) :- % case of nonempty list
!, % GREEN CUT for determinism
foldr(Foldy,Items,Starter,AccUpPrev), % recurse (NOT open to tail-call optimization)
call(Foldy,Item,AccUpPrev,AccUp). % call Foldy(Item,AccupPrev,AccUp) as last action
 
foldr(_,[],Starter,AccUp) :- % empty list: bounce Starter "upwards" into AccUp
AccUp=Starter. % unification not in head for clarity
</syntaxhighlight>
 
====Unit tests====
 
This is written using SWI-Prolog's [https://www.swi-prolog.org/pldoc/doc_for?object=section(%27packages/plunit.html%27) unit testing framework].
 
Functions (in predicate form) of interest for our test cases:
 
<syntaxhighlight lang="prolog">
:- use_module(library(clpfd)). % We are using #= instead of the raw "is".
 
foldy_len(_Item,ThreadIn,ThreadOut) :-
succ(ThreadIn,ThreadOut).
 
foldy_add(Item,ThreadIn,ThreadOut) :-
ThreadOut #= Item+ThreadIn.
 
foldy_mult(Item,ThreadIn,ThreadOut) :-
ThreadOut #= Item*ThreadIn.
 
foldy_squadd(Item,ThreadIn,ThreadOut) :-
ThreadOut #= Item+(ThreadIn^2).
 
% '[|]' is SWI-Prolog specific, replace by '.' as consbox constructor in other Prologs
 
foldy_build(Item,ThreadIn,ThreadOut) :-
ThreadOut = '[|]'(Item,ThreadIn).
 
foldy_join(Item,ThreadIn,ThreadOut) :-
(ThreadIn \= "")
-> with_output_to(string(ThreadOut),format("~w,~w",[Item,ThreadIn]))
; with_output_to(string(ThreadOut),format("~w",[Item])).
 
% '=..' ("univ") constructs a term from a list of functor and arguments
 
foldy_expr(Functor,Item,ThreadIn,ThreadOut) :-
ThreadOut =.. [Functor,Item,ThreadIn].
</syntaxhighlight>
 
<syntaxhighlight lang="prolog">
:- begin_tests(foldr).
 
in([1,2,3,4,5]).
 
ffr(Foldy,List,Starter,AccUp) :- foldr(Foldy,List,Starter,AccUp).
 
test(foo_foldr_len) :- in(L),ffr(foldy_len , L , 0 , R), R=5.
test(foo_foldr_add) :- in(L),ffr(foldy_add , L , 0 , R), R=15.
test(foo_foldr_mult) :- in(L),ffr(foldy_mult , L , 1 , R), R=120.
test(foo_foldr_build) :- in(L),ffr(foldy_build , L , [] , R), R=[1,2,3,4,5].
test(foo_foldr_squadd) :- in(L),ffr(foldy_squadd , L , 0 , R), R=507425426245.
test(foo_foldr_join) :- in(L),ffr(foldy_join , L , "" , R), R="1,2,3,4,5".
test(foo_foldr_expr) :- in(L),ffr(foldy_expr(*) , L , 1 , R), R=1*(2*(3*(4*(5*1)))).
 
test(foo_foldr_len_empty) :- ffr(foldy_len , [], 0 , R), R=0.
test(foo_foldr_add_empty) :- ffr(foldy_add , [], 0 , R), R=0.
test(foo_foldr_mult_empty) :- ffr(foldy_mult , [], 1 , R), R=1.
test(foo_foldr_build_empty) :- ffr(foldy_build , [], [] , R), R=[].
test(foo_foldr_squadd_empty) :- ffr(foldy_squadd , [], 0 , R), R=0.
test(foo_foldr_join_empty) :- ffr(foldy_join , [], "" , R), R="".
test(foo_foldr_expr_empty) :- ffr(foldy_expr(*) , [], 1 , R), R=1.
 
% library(apply) has no "foldr" so no comparison tests!
 
:- end_tests(foldr).
 
 
:- begin_tests(foldl).
 
in([1,2,3,4,5]).
 
ffl(Foldy,List,Starter,Result) :- foldl(Foldy,List,Starter,Result).
 
test(foo_foldl_len) :- in(L),ffl(foldy_len , L , 0 , R), R=5.
test(foo_foldl_add) :- in(L),ffl(foldy_add , L, 0 , R), R=15.
test(foo_foldl_mult) :- in(L),ffl(foldy_mult , L, 1 , R), R=120.
test(foo_foldl_build) :- in(L),ffl(foldy_build , L, [] , R), R=[5,4,3,2,1].
test(foo_foldl_squadd) :- in(L),ffl(foldy_squadd , L, 0 , R), R=21909.
test(foo_foldl_join) :- in(L),ffl(foldy_join , L, "" , R), R="5,4,3,2,1".
test(foo_foldl_expr) :- in(L),ffl(foldy_expr(*) , L, 1 , R), R=5*(4*(3*(2*(1*1)))).
 
test(foo_foldl_len_empty) :- ffl(foldy_len , [], 0 , R), R=0.
test(foo_foldl_add_empty) :- ffl(foldy_add , [], 0 , R), R=0.
test(foo_foldl_mult_empty) :- ffl(foldy_mult , [], 1 , R), R=1.
test(foo_foldl_build_empty) :- ffl(foldy_build , [], [] , R), R=[].
test(foo_foldl_squadd_empty) :- ffl(foldy_squadd , [], 0 , R), R=0.
test(foo_foldl_join_empty) :- ffl(foldy_join , [], "" , R), R="".
test(foo_foldl_expr_empty) :- ffl(foldy_expr(*) , [], 1 , R), R=1.
 
:- end_tests(foldl).
 
rt :- run_tests(foldr),run_tests(foldl).
</syntaxhighlight>
=={{header|PureBasic}}==
<syntaxhighlight lang="purebasic">Procedure.i reduce(List l(),op$="+")
If FirstElement(l())
x=l()
While NextElement(l())
Select op$
Case "+" : x+l()
Case "-" : x-l()
Case "*" : x*l()
EndSelect
Wend
EndIf
ProcedureReturn x
EndProcedure
 
NewList fold()
For i=1 To 5 : AddElement(fold()) : fold()=i : Next
 
Debug reduce(fold())
Debug reduce(fold(),"-")
Debug reduce(fold(),"*")</syntaxhighlight>
{{out}}
<pre>15
-13
120</pre>
=={{header|Python}}==
<syntaxhighlight lang ="python">>>> from operator# importPython add2.X
>>> from operator import add
>>> listoflists = [['the', 'cat'], ['sat', 'on'], ['the', 'mat']]
>>> help(reduce)
Line 1,143 ⟶ 2,425:
>>> reduce(add, listoflists, [])
['the', 'cat', 'sat', 'on', 'the', 'mat']
>>> </langsyntaxhighlight>
===Additional example===
<syntaxhighlight lang ="python">from functools# importPython reduce3.X
 
from functools import reduce
from operator import add, mul
 
Line 1,156 ⟶ 2,440:
concatenation = reduce(lambda a, b: str(a) + str(b), nums)
 
print(summation, product, concatenation)</langsyntaxhighlight>
=={{header|Quackery}}==
Among its many other uses, <code>witheach</code> can act like reduce. In the Quackery shell (REPL):
<syntaxhighlight lang="quackery">/O> 0 ' [ 1 2 3 4 5 ] witheach +
... 1 ' [ 1 2 3 4 5 ] witheach *
...
 
Stack: 15 120</syntaxhighlight>
=={{header|R}}==
 
Sum the numbers in a vector:
 
<syntaxhighlight lang="r">
Reduce('+', c(2,30,400,5000))
5432
</syntaxhighlight>
 
Put a 0 between each pair of numbers:
 
<syntaxhighlight lang="r">
Reduce(function(a,b){c(a,0,b)}, c(2,3,4,5))
2 0 3 0 4 0 5
</syntaxhighlight>
 
Generate all prefixes of a string:
 
<syntaxhighlight lang="r">
Reduce(paste0, unlist(strsplit("freedom", NULL)), accum=T)
"f" "fr" "fre" "free" "freed" "freedo" "freedom"
</syntaxhighlight>
 
Filter and map:
 
<syntaxhighlight lang="r">
Reduce(function(x,acc){if (0==x%%3) c(x*x,acc) else acc}, 0:22,
init=c(), right=T)
0 9 36 81 144 225 324 441
</syntaxhighlight>
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(define (fold f xs init)
Line 1,169 ⟶ 2,488:
 
(fold + '(1 2 3) 0) ; the result is 6
</syntaxhighlight>
</lang>
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2018.03}}
Any associative infix operator, either built-in or user-defined, may be turned into a reduce operator by putting it into square brackets (known as "the reduce metaoperator") and using it as a list operator. The operations will work left-to-right or right-to-left automatically depending on the natural associativity of the base operator.
<syntaxhighlight lang="raku" line>my @list = 1..10;
say [+] @list;
say [*] @list;
say [~] @list;
say min @list;
say max @list;
say [lcm] @list;</syntaxhighlight>
{{out}}
<pre>55
3628800
12345678910
1
10
2520</pre>
In addition to the reduce metaoperator, a general higher-order function, <tt>reduce</tt>, can apply any appropriate function. Reproducing the above in this form, using the function names of those operators, we have:
<syntaxhighlight lang="raku" line>my @list = 1..10;
say reduce &infix:<+>, @list;
say reduce &infix:<*>, @list;
say reduce &infix:<~>, @list;
say reduce &infix:<min>, @list;
say reduce &infix:<max>, @list;
say reduce &infix:<lcm>, @list;</syntaxhighlight>
=={{header|Refal}}==
<syntaxhighlight lang="refal">$ENTRY Go {
, 1 2 3 4 5 6 7: e.List
= <Prout <Reduce Add e.List>>
<Prout <Reduce Mul e.List>>;
};
 
Reduce {
s.F t.I = t.I;
s.F t.I t.J e.X = <Reduce s.F <Mu s.F t.I t.J> e.X>;
};</syntaxhighlight>
{{out}}
<pre>28
5040</pre>
 
=={{header|REXX}}==
This REXX example is modeled after the Perl 6Raku example &nbsp; (it is NOT a translation).
 
<lang rexx>/*REXX program demonstrates a method for catamorphism for some simple functions. */
Also, a &nbsp; '''list''' &nbsp; and &nbsp; '''show''' &nbsp; function were added, although they
aren't a catamorphism, as they don't produce or reduce the values to a &nbsp; ''single'' &nbsp; value, but
are included here to help display the values in the list.
<syntaxhighlight lang="rexx">/*REXX program demonstrates a method for catamorphism for some simple functions. */
@list= 1 2 3 4 5 6 7 8 9 10
say 'showlist:' fold(@list, 'show' "list")
say ' sum:' fold(@list, ' "+'" )
say 'prod:' fold(@list, ' "*'" )
say ' cat:' fold(@list, ' "||'" )
say ' min:' fold(@list, ' "min'" )
say ' max:' fold(@list, ' "max'" )
say ' avg:' fold(@list, ' "avg'" )
say ' GCD:' fold(@list, ' "GCD'" )
say ' LCM:' fold(@list, ' "LCM'" )
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
fold: procedure; parse arg z; arg ,f; z = space(z); BIFs= 'MIN MAX LCM GCD'
za= translate(z, f, ' '); zf= f"("translate(z, ',' , " ")')'
if f==" '+"' | f=='"*'" then interpret "return" za
if f== '||' then return space(z, 0)
if f== 'AVG' then interpret "return" fold(z, '+') "/" words(z)
if wordpos(f, BIFs)\==0 then interpret "return" zf
if f=='SHOWLIST' | f=="SHOW" then return z
return 'illegal function:' arg(2)
/*──────────────────────────────────────────────────────────────────────────────────────*/
lcmGCD: procedure; $=; do j=1 for arg(); $= $ arg(j); end /*j*/
x=abs(word($,1)) /* [↑] build a list of arguments. end /*j*/
parse var $ x z .; if x=0 then x= z do k=2 to words($); !=abs(word($,k)); if !==0 then/* return[↑] 0build an arg list.*/
x= abs(x)
x=x*! / gcd(x,!) /*have GCD do the heavy lifting.*/
end do /*k*/=2 to words($); y= abs( word($, k)); if y=0 then iterate
do until _=0; _= x // y; x= y; y= _
end /*until*/
end /*k*/
return x
/*──────────────────────────────────────────────────────────────────────────────────────*/
gcdLCM: procedure; $=; do j=1 for arg(); $= $ arg(j); end /*j*/
parse var $ x z .; if x=0 then x=z end /* [↑] build a list of arguments.j*/
x= abs(word($, 1)) /* [↑] build an arg list.*/
x=abs(x)
do k=2 to words($); != y=abs(word($, k)); if y=!=0 then iteratereturn 0
dox= untilx*! _==0; / _=GCD(x//y;, !) x=y; y=_; end /*untilGCD does the heavy work*/
end /*k*/
return x</langsyntaxhighlight>
'''{{out|output'''|:}}
<pre>
list: 1 2 3 4 5 6 7 8 9 10
Line 1,223 ⟶ 2,589:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
n = list(10)
for i = 1 to 10
Line 1,230 ⟶ 2,596:
see " +: " + cat(10,"+") + nl+
" -: " + cat(10,"-") + nl +
" *: " + cat(10,"*") + nl +
" /: " + cat(10,"/") + nl+
" ^: " + cat(10,"^") + nl +
"min: " + cat(10,"min") + nl+
"max: " + cat(10,"max") + nl+
"avg: " + cat(10,"avg") + nl +
"cat: " + cat(10,"cat") + nl
func cat count,op
cat = n[1]
cat2 = ""
for i = 2 to count
switch op
on "+" cat += n[i]
on "-" cat -= n[i]
on "*" cat *= n[i]
on "/" cat /= n[i]
on "^" cat ^= n[i]
on "max" cat = max(cat,n[i])
on "min" cat = min(cat,n[i])
on "avg" cat += n[i]
on "cat" cat2 += string(n[i])
off
next
if op = "avg" cat = cat / count ok
if op = "cat" decimals(0) cat = string(n[1])+cat2 ok
return cat
</syntaxhighlight>
</lang>
=={{header|RPL}}==
≪ → array op
≪ array 1 GET 2
'''WHILE''' DUP array SIZE ≤ '''REPEAT'''
array OVER GET ROT SWAP op EVAL
SWAP 1 +
'''END''' DROP
≫ ≫ '<span style="color:blue">REDUCE</span>' STO
 
[ 1 2 3 4 5 6 7 8 9 10 ] ≪ + ≫ <span style="color:blue">REDUCE</span>
[ 1 2 3 4 5 6 7 8 9 10 ] ≪ - ≫ <span style="color:blue">REDUCE</span>
[ 1 2 3 4 5 6 7 8 9 10 ] ≪ * ≫ <span style="color:blue">REDUCE</span>
[ 1 2 3 4 5 6 7 8 9 10 ] ≪ MAX ≫ <span style="color:blue">REDUCE</span>
[ 1 2 3 4 5 6 7 8 9 10 ] ≪ SQ + ≫ <span style="color:blue">REDUCE</span>
{{out}}
<pre>
5: 55
4: -53
3: 3628800
2: 10
1: 385
</pre>
From HP-48G models, a built-in function named <code>STREAM</code> performs exactly the same as the above <code>REDUCE</code> one, but only with lists.
 
=={{header|Ruby}}==
The method inject (and it's alias reduce) can be used in several ways; the simplest is to give a methodname as argument:
<langsyntaxhighlight lang="ruby"># sum:
p (1..10).inject(:+)
# smallest number divisible by all numbers from 1 to 20:
p (1..20).inject(:lcm) #lcm: lowest common multiple
</langsyntaxhighlight>The most versatile way uses a accumulator object (memo) and a block. In this example Pascal's triangle is generated by using an array [1,1] and inserting the sum of each consecutive pair of numbers from the previous row.
<langsyntaxhighlight lang="ruby">p row = [1]
10.times{p row = row.each_cons(2).inject([1,1]){|ar,(a,b)| ar.insert(-2, a+b)} }
 
Line 1,278 ⟶ 2,667:
# [1, 6, 15, 20, 15, 6, 1]
# etc
</syntaxhighlight>
</lang>
 
=={{header|Run BASIC}}==
<langsyntaxhighlight lang="runbasic">for i = 1 to 10 :n(i) = i:next i
 
print " +: ";" ";cat(10,"+")
Line 1,308 ⟶ 2,697:
if op$ = "avg" then cat = cat / count
if op$ = "cat" then cat = val(str$(n(1))+cat$)
end function</langsyntaxhighlight>
<pre> +: 55
-: -53
Line 1,318 ⟶ 2,707:
avg: 5.5
cat: 12345678910</pre>
=={{header|Rust}}==
 
<syntaxhighlight lang="rust">fn main() {
=={{header|Sidef}}==
println!("Sum: {}", (1..10).fold(0, |acc, n| acc + n));
<lang ruby>say (1..10 -> reduce('+'));
println!("Product: {}", (1..10).fold(1, |acc, n| acc * n));
say (1..10 -> reduce{|a,b| a + b});</lang>
let chars = ['a', 'b', 'c', 'd', 'e'];
println!("Concatenation: {}",
chars.iter().map(|&c| (c as u8 + 1) as char).collect::<String>());
}</syntaxhighlight>
 
{{out}}
<pre>
Sum: 45
Product: 362880
Concatenation: bcdef
</pre>
=={{header|Scala}}==
<syntaxhighlight lang="scala">object Main extends App {
val a = Seq(1, 2, 3, 4, 5)
println(s"Array : ${a.mkString(", ")}")
println(s"Sum : ${a.sum}")
println(s"Difference : ${a.reduce { (x, y) => x - y }}")
println(s"Product : ${a.product}")
println(s"Minimum : ${a.min}")
println(s"Maximum : ${a.max}")
}</syntaxhighlight>
=={{header|Scheme}}==
===Implementation===
reduce implemented for a single list:
<syntaxhighlight lang="scheme">(define (reduce fn init lst)
(do ((val init (fn (car rem) val)) ; accumulated value passed as second argument
(rem lst (cdr rem)))
((null? rem) val)))
 
(display (reduce + 0 '(1 2 3 4 5))) (newline) ; => 15
(display (reduce expt 2 '(3 4))) (newline) ; => 262144</syntaxhighlight>
===Using SRFI 1===
There is also an implementation of fold and fold-right in SRFI-1, for lists.
 
These take a two-argument procedure: (lambda (value acc) ...) where value is the next value in the list, and acc is the accumulated value. The initial value is used for the first value of acc.
 
<pre>
> (import (srfi 1))
> (fold + 0 '(1 2 3 4 5))
15
> (fold expt 2 '(3 4)) ; => (expt 4 (expt 3 2))
262144
> (fold-right expt 2 '(3 4)) ; => (expt 3 (expt 4 2))
43046721
</pre>
 
More than one list may be folded over, when the function is passed one item from each list plus the accumulated value:
 
<pre>
> (fold + 0 '(1 2 3) '(4 5 6)) ; add up all the numbers in all the lists
21
</pre>
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">say (1..10 -> reduce('+'));
say (1..10 -> reduce{|a,b| a + b});</syntaxhighlight>
=={{header|Standard ML}}==
<langsyntaxhighlight lang="sml">- val nums = [1,2,3,4,5,6,7,8,9,10];
val nums = [1,2,3,4,5,6,7,8,9,10] : int list
- val sum = foldl op+ 0 nums;
val sum = 55 : int
- val product = foldl op* 1 nums;
val product = 3628800 : int</langsyntaxhighlight>
=={{header|Swift}}==
<syntaxhighlight lang="swift">let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 
print(nums.reduce(0, +))
print(nums.reduce(1, *))
print(nums.reduce("", { $0 + String($1) }))</syntaxhighlight>
 
{{out}}
<pre>55
3628800
12345678910</pre>
=={{header|Tailspin}}==
It is probably easier to just write the whole thing as an inline transform rather than create a utility.
<syntaxhighlight lang="tailspin">
[1..5] -> \(@: $(1); $(2..last)... -> @: $@ + $; $@!\) -> '$;
' -> !OUT::write
[1..5] -> \(@: $(1); $(2..last)... -> @: $@ - $; $@!\) -> '$;
' -> !OUT::write
[1..5] -> \(@: $(1); $(2..last)... -> @: $@ * $; $@!\) -> '$;
' -> !OUT::write
</syntaxhighlight>
{{out}}
<pre>
15
-13
120
</pre>
 
If you really want to make a utility, it could look like this:
<syntaxhighlight lang="tailspin">
templates fold&{op:}
@: $(1);
$(2..last)... -> @: [$@, $] -> op;
$@ !
end fold
 
templates add
$(1) + $(2) !
end add
 
templates mul
$(1) * $(2) !
end mul
 
[1..5] -> fold&{op:add} -> '$;
' -> !OUT::write
 
[1..5] -> fold&{op:mul} -> '$;
' -> !OUT::write
</syntaxhighlight>
{{out}}
<pre>
15
120
</pre>
=={{header|Tcl}}==
Tcl does not come with a built-in <tt>fold</tt> command, but it is easy to construct:
<langsyntaxhighlight lang="tcl">proc fold {lambda zero list} {
set accumulator $zero
foreach item $list {
Line 1,339 ⟶ 2,837:
}
return $accumulator
}</langsyntaxhighlight>
Demonstrating:
<langsyntaxhighlight lang="tcl">set 1to5 {1 2 3 4 5}
 
puts [fold {{a b} {expr {$a+$b}}} 0 $1to5]
puts [fold {{a b} {expr {$a*$b}}} 1 $1to5]
puts [fold {{a b} {return $a,$b}} x $1to5]</langsyntaxhighlight>
{{out}}
<pre>
Line 1,353 ⟶ 2,851:
</pre>
Note that these particular operations would more conventionally be written as:
<langsyntaxhighlight lang="tcl">puts [::tcl::mathop::+ {*}$1to5]
puts [::tcl::mathop::* {*}$1to5]
puts x,[join $1to5 ,]</langsyntaxhighlight>
But those are not general catamorphisms.
=={{header|uBasic/4tH}}==
{{trans|FreeBASIC}}
uBasic/4tH has only got one single array so passing its address makes little sense. Instead, its bounds are passed.
<syntaxhighlight lang="uBasic/4tH">For x = 1 To 5 : @(x-1) = x : Next ' initialize array
' try different reductions
Print "Sum is : "; FUNC(_Reduce(_add, 5))
Print "Difference is : "; FUNC(_Reduce(_subtract, 5))
Print "Product is : "; FUNC(_Reduce(_multiply, 5))
Print "Maximum is : "; FUNC(_Reduce(_max, 5))
Print "Minimum is : "; FUNC(_Reduce(_min, 5))
 
End
' several functions
_add Param (2) : Return (a@ + b@)
_subtract Param (2) : Return (a@ - b@)
_multiply Param (2) : Return (a@ * b@)
_min Param (2) : Return (Min (a@, b@))
_max Param (2) : Return (Max (a@, b@))
 
_Reduce
Param (2) ' function and array size
Local (2) ' loop index and result
' set result and iterate array
d@ = @(0) : For c@ = 1 To b@-1 : d@ = FUNC(a@ (d@, @(c@))) : Next
Return (d@)</syntaxhighlight>
This version incorporates a "no op" as well.
<syntaxhighlight lang="text">Push 5, 4, 3, 2, 1: s = Used() - 1
For x = 0 To s: @(x) = Pop(): Next
 
Print "Sum is : "; FUNC(_reduce(0, s, _add))
Print "Difference is : "; FUNC(_reduce(0, s, _subtract))
Print "Product is : "; FUNC(_reduce(0, s, _multiply))
Print "Maximum is : "; FUNC(_reduce(0, s, _max))
Print "Minimum is : "; FUNC(_reduce(0, s, _min))
Print "No op is : "; FUNC(_reduce(0, s, _noop))
End
 
_reduce
Param (3)
Local (2)
 
If (Line(c@) = 0) + ((b@ - a@) < 1) Then Return (0)
d@ = @(a@)
For e@ = a@ + 1 To b@
d@ = FUNC(c@ (d@, @(e@)))
Next
Return (d@)
_add Param (2) : Return (a@ + b@)
_subtract Param (2) : Return (a@ - b@)
_multiply Param (2) : Return (a@ * b@)
_max Param (2) : Return (Max(a@, b@))
_min Param (2) : Return (Min(a@, b@))</syntaxhighlight>
{{out}}
<pre>Sum is : 15
Difference is : -13
Product is : 120
Maximum is : 5
Minimum is : 1
No op is : 0
 
0 OK, 0:378
</pre>
 
=={{header|VBA}}==
<syntaxhighlight lang="vb">Public Sub reduce()
s = [{1,2,3,4,5}]
Debug.Print WorksheetFunction.Sum(s)
Debug.Print WorksheetFunction.Product(s)
End Sub</syntaxhighlight>
=={{header|V (Vlang)}}==
{{trans|go}}
<syntaxhighlight lang="v (vlang)">
fn main() {
n := [1, 2, 3, 4, 5]
println(reduce(add, n))
println(reduce(sub, n))
println(reduce(mul, n))
}
fn add(a int, b int) int { return a + b }
fn sub(a int, b int) int { return a - b }
fn mul(a int, b int) int { return a * b }
fn reduce(rf fn(int, int) int, m []int) int {
mut r := m[0]
for v in m[1..] {
r = rf(r, v)
}
return r
}</syntaxhighlight>
 
{{out}}
<pre>
15
-13
120
</pre>
 
=={{header|WDTE}}==
Translated from the JavaScript ES6 example with a few modifications.
 
<syntaxhighlight lang="wdte">let a => import 'arrays';
let s => import 'stream';
let str => import 'strings';
 
# Sum of [1, 10]:
let nums => [1; 2; 3; 4; 5; 6; 7; 8; 9; 10];
a.stream nums -> s.reduce 0 + -- io.writeln io.stdout;
 
# As an alternative to an array, a range stream can be used. Here's the product of [1, 11):
s.range 1 11 -> s.reduce 1 * -- io.writeln io.stdout;
 
# And here's a concatenation:
s.range 1 11 -> s.reduce '' (str.format '{}{}') -- io.writeln io.stdout;</syntaxhighlight>
=={{header|Wortel}}==
You can reduce an array with the <code>!/</code> operator.
<langsyntaxhighlight lang="wortel">!/ ^+ [1 2 3] ; returns 6</langsyntaxhighlight>
If you want to reduce with an initial value, you'll need the <code>@fold</code> operator.
<langsyntaxhighlight lang="wortel">@fold ^+ 1 [1 2 3] ; returns 7</langsyntaxhighlight>
 
{{out}}
<pre>55
3628800
12345678910</pre>
=={{header|Wren}}==
<syntaxhighlight lang="wren">var a = [1, 2, 3, 4, 5]
var sum = a.reduce { |acc, i| acc + i }
var prod = a.reduce { |acc, i| acc * i }
var sumSq = a.reduce { |acc, i| acc + i*i }
System.print(a)
System.print("Sum is %(sum)")
System.print("Product is %(prod)")
System.print("Sum of squares is %(sumSq)")</syntaxhighlight>
 
{{out}}
<pre>
[1, 2, 3, 4, 5]
Sum is 15
Product is 120
Sum of squares is 55
</pre>
 
=={{header|Zig}}==
'''Works with:''' 0.10.x, 0.11.x, 0.12.0-dev.1591+3fc6a2f11
 
===Reduce a slice===
<syntaxhighlight lang="zig">/// Asserts that `array`.len >= 1.
pub fn reduce(comptime T: type, comptime applyFn: fn (T, T) T, array: []const T) T {
var val: T = array[0];
for (array[1..]) |elem| {
val = applyFn(val, elem);
}
return val;
}</syntaxhighlight>
 
Usage:
 
<syntaxhighlight lang="zig">const std = @import("std");
 
fn add(a: i32, b: i32) i32 {
return a + b;
}
 
fn mul(a: i32, b: i32) i32 {
return a * b;
}
 
fn min(a: i32, b: i32) i32 {
return @min(a, b);
}
 
fn max(a: i32, b: i32) i32 {
return @max(a, b);
}
 
pub fn main() void {
const arr: [5]i32 = .{ 1, 2, 3, 4, 5 };
std.debug.print("Array: {any}\n", .{arr});
std.debug.print(" * Reduce with add: {d}\n", .{reduce(i32, add, &arr)});
std.debug.print(" * Reduce with mul: {d}\n", .{reduce(i32, mul, &arr)});
std.debug.print(" * Reduce with min: {d}\n", .{reduce(i32, min, &arr)});
std.debug.print(" * Reduce with max: {d}\n", .{reduce(i32, max, &arr)});
}</syntaxhighlight>
 
{{out}}
<pre>
Array: { 1, 2, 3, 4, 5 }
* Reduce with add: 15
* Reduce with mul: 120
* Reduce with min: 1
* Reduce with max: 5
</pre>
 
===Reduce a vector===
 
We use @reduce builtin function here to leverage special instructions if available, but only small set of reduce operators are available.
@Vector and related builtings will use SIMD instructions if possible. If target platform does not support SIMD instructions, vectors operations will be compiled like in previous example (represented as arrays and operating with one element at a time).
 
<syntaxhighlight lang="zig">const std = @import("std");
 
pub fn main() void {
const vec: @Vector(5, i32) = .{ 1, 2, 3, 4, 5 };
std.debug.print("Vec: {any}\n", .{vec});
std.debug.print(" * Reduce with add: {d}\n", .{@reduce(.Add, vec)});
std.debug.print(" * Reduce with mul: {d}\n", .{@reduce(.Mul, vec)});
std.debug.print(" * Reduce with min: {d}\n", .{@reduce(.Min, vec)});
std.debug.print(" * Reduce with max: {d}\n", .{@reduce(.Max, vec)});
}</syntaxhighlight>
 
{{out}}
<pre>
Vec: { 1, 2, 3, 4, 5 }
* Reduce with add: 15
* Reduce with mul: 120
* Reduce with min: 1
* Reduce with max: 5
</pre>
 
Note that std.builtin.ReduceOp.Add and std.builtin.ReduceOp.Mul operators wrap on overflow and underflow, unlike regular Zig operators, where they are considered illegal behaviour and checked in safe optimize modes. This can be demonstrated by this example (ReleaseSafe optimize mode, zig 0.11.0, Linux 6.5.11 x86_64):
 
<syntaxhighlight lang="zig">const std = @import("std");
 
pub fn main() void {
const vec: @Vector(2, i32) = .{ std.math.minInt(i32), std.math.minInt(i32) + 1 };
std.debug.print("Vec: {any}\n", .{vec});
std.debug.print(" * Reduce with .Add: {d}\n", .{@reduce(.Add, vec)});
std.debug.print(" * Reduce with .Mul: {d}\n", .{@reduce(.Mul, vec)});
 
var zero: usize = 0; // Small trick to make compiler not emit compile error for overflow below:
std.debug.print(" * Reduce with regular add operator: {d}\n", .{vec[zero] + vec[1]});
std.debug.print(" * Reduce with regular mul operator: {d}\n", .{vec[zero] * vec[1]});
}</syntaxhighlight>
 
{{out}}
<pre>
Vec: { -2147483648, -2147483647 }
* Reduce with .Add: 1
* Reduce with .Mul: -2147483648
thread 5908 panic: integer overflow
/home/bratishkaerik/test/catamorphism.zig:10:79: 0x20c4b0 in main (catamorphism)
std.debug.print(" * Reduce with regular add operator: {d}\n", .{vec[zero] + vec[1]});
^
/usr/lib64/zig/0.11.0/lib/std/start.zig:564:22: 0x20bee4 in posixCallMainAndExit (catamorphism)
root.main();
^
/usr/lib64/zig/0.11.0/lib/std/start.zig:243:5: 0x20bdc1 in _start (catamorphism)
asm volatile (switch (native_arch) {
^
???:?:?: 0x0 in ??? (???)
[1] 5908 IOT instruction ./catamorphism
</pre>
 
For well-defined overflow/underflow behaviour you can use wrapping and saturating operators (for addition they are +% and +| respectively). With +% and *% (wrapping multiplication) operators, behaviour should be identical to .Add and .Mul reduce operators.
 
=={{header|zkl}}==
Most sequence objects in zkl have a reduce method.
<langsyntaxhighlight lang="zkl">T("foo","bar").reduce(fcn(p,n){p+n}) //--> "foobar"
"123four5".reduce(fcn(p,c){p+(c.matches("[0-9]") and c or 0)}, 0) //-->11
File("foo.zkl").reduce('+(1).fpM("0-"),0) //->5 (lines in file)</langsyntaxhighlight>
=={{header|ZX Spectrum Basic}}==
{{trans|BBC_BASIC}}
<syntaxhighlight lang="zxbasic">10 DIM a(5)
20 FOR i=1 TO 5
30 READ a(i)
40 NEXT i
50 DATA 1,2,3,4,5
60 LET o$="+": GO SUB 1000: PRINT tmp
70 LET o$="-": GO SUB 1000: PRINT tmp
80 LET o$="*": GO SUB 1000: PRINT tmp
90 STOP
1000 REM Reduce
1010 LET tmp=a(1)
1020 FOR i=2 TO 5
1030 LET tmp=VAL ("tmp"+o$+"a(i)")
1040 NEXT i
1050 RETURN </syntaxhighlight>
56

edits