Catamorphism: Difference between revisions

m
syntax highlighting fixup automation
m (syntax highlighting fixup automation)
Line 14:
 
=={{header|11l}}==
<langsyntaxhighlight 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))</langsyntaxhighlight>
{{out}}
<pre>
Line 27:
=={{header|6502 Assembly}}==
{{works with|https://skilldrick.github.io/easy6502/ Easy6502}}
<langsyntaxhighlight lang=6502asm>define catbuf $10
define catbuf_temp $12
 
Line 71:
inx
cpx #$ff
bne clear_ram</langsyntaxhighlight>
 
=={{header|ABAP}}==
This works in ABAP version 7.40 and above.
 
<langsyntaxhighlight lang=ABAP>
report z_catamorphism.
 
Line 121:
for string in strings
next text = |{ text } { string }| ) }|, /.
</syntaxhighlight>
</lang>
 
{{out}}
Line 138:
=={{header|Ada}}==
 
<langsyntaxhighlight lang=Ada>with Ada.Text_IO;
 
procedure Catamorphism is
Line 166:
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}}
Line 173:
 
=={{header|Aime}}==
<langsyntaxhighlight lang=aime>integer s;
 
s = 0;
list(1, 2, 3, 4, 5, 6, 7, 8, 9).ucall(add_i, 1, s);
o_(s, "\n");</langsyntaxhighlight>
{{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 201:
; 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 212:
<em>Reduce</em> is a built-in APL operator, written as <code>/</code>.
 
<langsyntaxhighlight lang=apl> +/ 1 2 3 4 5 6 7
28
×/ 1 2 3 4 5 6 7
5040</langsyntaxhighlight>
 
For built-in functions, the seed value is automatically chosen to make sense.
 
<langsyntaxhighlight lang=apl> +/⍬
0
×/⍬
1
⌈/⍬ ⍝ this gives the minimum supported value
¯1.797693135E308</langsyntaxhighlight>
 
For user-supplied functions, the last element in the list is considered the seed.
Line 230:
called, and calling <code>F/</code> with the empty list is an error.
 
<langsyntaxhighlight lang=apl> {⎕←'Input:',⍺,⍵ ⋄ ⍺+⍵}/ 1 2 3 4 5
Input: 4 5
Input: 3 9
Line 239:
1
{⎕←'Input:',⍺,⍵ ⋄ ⍺+⍵}/ ⍬
DOMAIN ERROR</langsyntaxhighlight>
 
=={{header|AppleScript}}==
Line 248:
(Note that to obtain first-class functions from user-defined AppleScript handlers, we have to 'lift' them into script objects).
 
<langsyntaxhighlight lang=AppleScript>---------------------- CATAMORPHISMS ---------------------
 
-- the arguments available to the called function f(a, x, i, l) are
Line 368:
end script
end if
end mReturn</langsyntaxhighlight>
{{out}}
<pre>{55, 3628800, "12345678910"}</pre>
Line 374:
=={{header|Arturo}}==
 
<langsyntaxhighlight lang=rebol>; find the sum, with seed:0 (default)
print fold [1 2 3 4] => add
 
; find the product, with seed:1
print fold [1 2 3 4] .seed:1 => mul</langsyntaxhighlight>
 
{{out}}
Line 388:
==={{header|BASIC256}}===
{{trans|Run BASIC}}
<langsyntaxhighlight lang=BASIC256>arraybase 1
global n
dim n = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Line 427:
if op$ = "cat" then temp = int(string(n[1]) + temp$)
return temp
end function</langsyntaxhighlight>
 
 
Line 433:
{{works with|QBasic|1.1}}
{{trans|Run BASIC}}
<langsyntaxhighlight lang=qbasic>DIM SHARED n(10)
FOR i = 1 TO 10: n(i) = i: NEXT i
 
Line 466:
PRINT "min: "; " "; cat(10, "min")
PRINT "max: "; " "; cat(10, "max")
PRINT "avg: "; " "; cat(10, "avg")</langsyntaxhighlight>
 
 
==={{header|True BASIC}}===
<langsyntaxhighlight lang=qbasic>SHARE n(10)
FOR i = 1 to 10
LET n(i) = i
Line 515:
PRINT "avg: "; " "; cat(10, "avg")
PRINT "cat: "; " "; cat(10, "cat")
END</langsyntaxhighlight>
 
 
==={{header|Yabasic}}===
{{trans|Run BASIC}}
<langsyntaxhighlight lang=freebasic>dim n(10)
for i = 1 to 10 : n(i) = i : next i
Line 547:
if op$ = "avg" cat = cat / cont
return cat
end sub</langsyntaxhighlight>
 
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang=bbcbasic>
DIM a(4)
a() = 1, 2, 3, 4, 5
Line 567:
NEXT
= tmp
</syntaxhighlight>
</lang>
 
{{out}}
Line 575:
 
=={{header|BCPL}}==
<langsyntaxhighlight lang=bcpl>get "libhdr"
 
let reduce(f, v, len, seed) =
Line 589:
writef("%N*N", reduce(add, nums, 7, 0))
writef("%N*N", reduce(mul, nums, 7, 1))
$)</langsyntaxhighlight>
{{out}}
<pre>28
Line 622:
 
=={{header|Bracmat}}==
<langsyntaxhighlight lang=bracmat>( ( fold
= f xs init first rest
. !arg:(?f.?xs.?init)
Line 639:
& (product=a b.!arg:(?a.?b)&!a*!b)
& out$(fold$(product.1 2 3 4 5.1))
);</langsyntaxhighlight>
Output:
<pre>15
Line 645:
 
=={{header|C}}==
<langsyntaxhighlight lang=C>#include <stdio.h>
 
typedef int (*intFn)(int, int);
Line 668:
printf("%d\n", reduce(mul, 5, nums));
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 676:
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang=csharp>var nums = Enumerable.Range(1, 10);
 
int summation = nums.Aggregate((a, b) => a + b);
Line 684:
string concatenation = nums.Aggregate(String.Empty, (a, b) => a.ToString() + b.ToString());
 
Console.WriteLine("{0} {1} {2}", summation, product, concatenation);</langsyntaxhighlight>
 
=={{header|C++}}==
<langsyntaxhighlight lang=cpp>#include <iostream>
#include <numeric>
#include <functional>
Line 700:
std::cout << "nums_added: " << nums_added << std::endl;
std::cout << "nums_other: " << nums_other << std::endl;
}</langsyntaxhighlight>
 
{{out}}
Line 710:
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 716:
> (reduce + 100 '(1 2 3 4 5))
115
</syntaxhighlight>
</lang>
 
=={{header|CLU}}==
<langsyntaxhighlight lang=clu>% Reduction.
% First type = sequence type (must support S$elements and yield R)
% Second type = right (input) datatype
Line 753:
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</langsyntaxhighlight>
{{out}}
<pre>The sum of [1..10] is: 55
Line 759:
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang=lisp>; Basic usage
> (reduce #'* '(1 2 3 4 5))
120
Line 776:
; 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;
Line 791:
// 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 801:
 
=={{header|DCL}}==
<langsyntaxhighlight lang=DCL>$ list = "1,2,3,4,5"
$ call reduce list "+"
$ show symbol result
Line 826:
$ result == value
$ exit
$ endsubroutine</langsyntaxhighlight>
{{out}}
<pre>$ @catamorphism
Line 835:
=={{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 843:
!. reduce @+ [ 1 10 200 ] 4
!. reduce @- [ 1 10 200 ] 4
</syntaxhighlight>
</lang>
{{out}}
<pre>215
Line 851:
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang=scheme>
;; rem : the foldX family always need an initial value
;; fold left a list
Line 871:
(scanl * 1 '( 1 2 3 4 5))
→ (1 1 2 6 24 120)
</syntaxhighlight>
</lang>
 
=={{header|Elena}}==
ELENA 5.0 :
<langsyntaxhighlight lang=elena>import system'collections;
import system'routines;
import extensions;
Line 891:
console.printLine(summary," ",product," ",concatenation)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 898:
 
=={{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 925:
Nums),
{Summation, Product, Concatenation}.
</syntaxhighlight>
</lang>
 
Output:
Line 962:
 
{{Works with|Office 365 betas 2021}}
<langsyntaxhighlight lang=lisp>FOLDROW
=LAMBDA(op,
LAMBDA(a,
Line 1,045:
1
)
)</langsyntaxhighlight>
 
{{Out}}
Line 1,174:
=={{header|Factor}}==
 
<langsyntaxhighlight lang=factor>{ 1 2 4 6 10 } 0 [ + ] reduce .</langsyntaxhighlight>
{{out}}
<pre>
Line 1,210:
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 1,236:
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 1,247:
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 1,267:
 
: 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 1,287:
 
: count-lowercase ( c-addr u -- n )
0 -rot [: lowercase? if 1+ then ;] each-char ;</langsyntaxhighlight>
 
In these examples COUNT-LOWERCASE updates an accumulator, UPCASE
Line 1,294:
 
=={{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 <langsyntaxhighlight lang=Fortran> SUBROUTINE FOLD(t,F,i,ist,lst)
INTEGER t
BYNAME F
Line 1,302:
END SUBROUTINE FOLD !Result in temp.
 
temp = a(1); CALL FOLD(temp,temp*a(i),i,2,N)</langsyntaxhighlight>
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.
 
Line 1,311:
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. <langsyntaxhighlight 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.
Line 1,364:
WRITE (MSG,*) "Ivid",IFOLD(IVID,A,ENUFF)
END PROGRAM POKE
</syntaxhighlight>
</lang>
Output:
<pre>
Line 1,376:
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang=freebasic>' FB 1.05.0 Win64
 
Type IntFunc As Function(As Integer, As Integer) As Integer
Line 1,420:
Print "Press any key to quit"
Sleep
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,433:
 
=={{header|Go}}==
<langsyntaxhighlight lang=go>package main
 
import (
Line 1,457:
}
return r
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,467:
=={{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 1,479:
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 1,490:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang=haskell>main :: IO ()
main =
putStrLn . unlines $
Line 1,497:
, foldr ((++) . show) "" -- concatenation
] <*>
[[1 .. 10]]</langsyntaxhighlight>
{{Out}}
<pre>55
Line 1,505:
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:
 
<langsyntaxhighlight lang=haskell>import Data.Monoid
 
main :: IO ()
Line 1,516:
, (show . foldr (<>) mempty) (words
"Love is one damned thing after each other")
]</langsyntaxhighlight>
{{Out}}
<pre>55
Line 1,530:
 
Works in both languages:
<langsyntaxhighlight lang=unicon>procedure main(A)
write(A[1],": ",curry(A[1],A[2:0]))
end
Line 1,538:
every r := f(r, !A[2:0])
return r
end</langsyntaxhighlight>
 
Sample runs:
Line 1,553:
 
=={{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<langsyntaxhighlight lang=j>
1 * 2 * 3 * 20
1 * 2 * 60
1 * 120
120
</syntaxhighlight>
</lang>
What are the implications for -/ ?
For %/ ?
Line 1,574:
=={{header|Java}}==
{{works with|Java|8}}
<langsyntaxhighlight lang=java>import java.util.stream.Stream;
 
public class ReduceTask {
Line 1,582:
System.out.println(Stream.of(1, 2, 3, 4, 5).reduce(1, (a, b) -> a * b));
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,592:
===ES5===
 
<langsyntaxhighlight lang=javascript>var nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 
function add(a, b) {
Line 1,608:
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 lang=JavaScript>(function (xs) {
'use strict';
 
Line 1,633:
});
 
})([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);</langsyntaxhighlight>
 
{{Out}}
Line 1,642:
===ES6===
 
<langsyntaxhighlight 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</langsyntaxhighlight>
 
=={{header|jq}}==
Line 1,665:
=={{header|Julia}}==
{{Works with|Julia 1.2}}
<langsyntaxhighlight 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 [+, -, *]])</langsyntaxhighlight>
{{out}}
<pre>[15, -13, 120]
Line 1,674:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang=scala>fun main(args: Array<String>) {
val a = intArrayOf(1, 2, 3, 4, 5)
println("Array : ${a.joinToString(", ")}")
Line 1,682:
println("Minimum : ${a.reduce { x, y -> if (x < y) x else y }}")
println("Maximum : ${a.reduce { x, y -> if (x > y) x else y }}")
}</langsyntaxhighlight>
 
{{out}}
Line 1,696:
=={{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 1,711:
 
:- end_object.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,726:
{{trans|C}}
 
<langsyntaxhighlight lang=LOLCODE>HAI 1.3
 
HOW IZ I reducin YR array AN YR size AN YR fn
Line 1,752:
VISIBLE I IZ reducin YR array AN YR 5 AN YR mul MKAY
 
KTHXBYE</langsyntaxhighlight>
 
{{out}}
Line 1,760:
 
=={{header|Lua}}==
<langsyntaxhighlight lang=Lua>
table.unpack = table.unpack or unpack -- 5.1 compatibility
local nums = {1,2,3,4,5,6,7,8,9}
Line 1,791:
print("cat {1..9}: ",reduce(cat,table.unpack(nums)))
 
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,801:
 
=={{header|M2000 Interpreter}}==
<langsyntaxhighlight lang=M2000 Interpreter>
Module CheckIt {
Function Reduce (a, f) {
Line 1,822:
}
CheckIt
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,835:
=={{header|Maple}}==
The left fold operator in Maple is foldl, and foldr is the right fold operator.
<langsyntaxhighlight lang=Maple>> nums := seq( 1 .. 10 );
nums := 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
 
Line 1,842:
 
> foldr( `*`, 1, nums ); # compute product using foldr
3628800</langsyntaxhighlight>
Compute the horner form of a (sorted) polynomial:
<langsyntaxhighlight lang=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}}
<langsyntaxhighlight lang=min>(1 2 3 4) 0 '+ reduce puts! ; sum
(1 2 3 4) 1 '* reduce puts! ; product</langsyntaxhighlight>
{{out}}
<pre>
Line 1,870:
 
=={{header|Modula-2}}==
<langsyntaxhighlight lang=modula2>MODULE Catamorphism;
FROM InOut IMPORT WriteString, WriteCard, WriteLn;
 
Line 1,909:
 
BEGIN Demonstration;
END Catamorphism.</langsyntaxhighlight>
{{out}}
<pre>Sum of [1..5]: 15
Line 1,916:
=={{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 lang=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 1,938:
multiplication = foldr(numbers, a * b)
words = @["nim", "is", "cool"]
concatenation = foldr(words, a & b)</langsyntaxhighlight>
 
=={{header|Oberon-2}}==
{{Works with| oo2c Version 2}}
<langsyntaxhighlight lang=oberon2>
MODULE Catamorphism;
IMPORT
Line 2,015:
END
END Catamorphism.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,024:
 
=={{header|Objeck}}==
<langsyntaxhighlight lang=objeck>
use Collection;
 
Line 2,041:
return a * b;
}
}</langsyntaxhighlight>
Output
<pre>
Line 2,049:
 
=={{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 lang=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 reduceApp;
 
type
Line 2,128:
writeln(reduce(@sub,ma));
writeln(reduce(@mul,ma));
END.</langsyntaxhighlight>
output
<pre>-5,-4,-3,-2,-1,1,1,2,3,4,5
Line 2,137:
=={{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 2,144:
# 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}}==
{{trans|C}}
<!--<langsyntaxhighlight lang=Phix>(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<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>
Line 2,165:
<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>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 2,174:
 
=={{header|Phixmonti}}==
<langsyntaxhighlight lang=Phixmonti>include ..\Utilitys.pmt
 
def add + enddef
Line 2,193:
getid add reduce ?
getid sub reduce ?
getid mul reduce ?</langsyntaxhighlight>
 
 
=={{header|PicoLisp}}==
<langsyntaxhighlight lang=PicoLisp>(de reduce ("Fun" "Lst")
(let "A" (car "Lst")
(for "N" (cdr "Lst")
Line 2,207:
(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':
<langsyntaxhighlight lang=PowerShell>
1..5 | ForEach-Object -Begin {$result = 0} -Process {$result += $_} -End {$result}
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,226:
* '''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)])
 
<langsyntaxhighlight lang=Prolog>:- use_module(library(lambda)).
 
catamorphism :-
Line 2,237:
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 2,253:
* The list is terminated by the special atomic thing <code>[]</code> (the empty list)
 
<langsyntaxhighlight lang=Prolog>
% List to be folded:
%
Line 2,260:
% a b c d <-- list items/entries/elements/members
%
</syntaxhighlight>
</lang>
 
====linear <code>foldl</code>====
 
<langsyntaxhighlight lang=Prolog>
% Computes "Out" as:
%
Line 2,279:
foldl(_,[],Acc,Result) :- % case of empty list
Acc=Result. % unification not in head for clarity
</syntaxhighlight>
</lang>
 
====linear <code>foldr</code>====
 
<langsyntaxhighlight lang=Prolog>
% Computes "Out" as:
%
Line 2,297:
foldr(_,[],Starter,AccUp) :- % empty list: bounce Starter "upwards" into AccUp
AccUp=Starter. % unification not in head for clarity
</syntaxhighlight>
</lang>
 
====Unit tests====
Line 2,305:
Functions (in predicate form) of interest for our test cases:
 
<langsyntaxhighlight lang=Prolog>
:- use_module(library(clpfd)). % We are using #= instead of the raw "is".
 
Line 2,334:
foldy_expr(Functor,Item,ThreadIn,ThreadOut) :-
ThreadOut =.. [Functor,Item,ThreadIn].
</syntaxhighlight>
</lang>
 
<langsyntaxhighlight lang=Prolog>
:- begin_tests(foldr).
 
Line 2,389:
 
rt :- run_tests(foldr),run_tests(foldl).
</syntaxhighlight>
</lang>
 
=={{header|PureBasic}}==
<langsyntaxhighlight lang=PureBasic>Procedure.i reduce(List l(),op$="+")
If FirstElement(l())
x=l()
Line 2,411:
Debug reduce(fold())
Debug reduce(fold(),"-")
Debug reduce(fold(),"*")</langsyntaxhighlight>
{{out}}
<pre>15
Line 2,418:
 
=={{header|Python}}==
<langsyntaxhighlight lang=python>>>> # Python 2.X
>>> from operator import add
>>> listoflists = [['the', 'cat'], ['sat', 'on'], ['the', 'mat']]
Line 2,436:
>>> reduce(add, listoflists, [])
['the', 'cat', 'sat', 'on', 'the', 'mat']
>>> </langsyntaxhighlight>
===Additional example===
<langsyntaxhighlight lang=python># Python 3.X
 
from functools import reduce
Line 2,451:
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):
<langsyntaxhighlight lang=quackery>/O> 0 ' [ 1 2 3 4 5 ] witheach +
... 1 ' [ 1 2 3 4 5 ] witheach *
...
 
Stack: 15 120</langsyntaxhighlight>
 
=={{header|R}}==
Line 2,465:
Sum the numbers in a vector:
 
<syntaxhighlight lang=R>
<lang R>
Reduce('+', c(2,30,400,5000))
5432
</syntaxhighlight>
</lang>
 
Put a 0 between each pair of numbers:
 
<syntaxhighlight lang=R>
<lang R>
Reduce(function(a,b){c(a,0,b)}, c(2,3,4,5))
2 0 3 0 4 0 5
</syntaxhighlight>
</lang>
 
Generate all prefixes of a string:
 
<syntaxhighlight lang=R>
<lang R>
Reduce(paste0, unlist(strsplit("freedom", NULL)), accum=T)
"f" "fr" "fre" "free" "freed" "freedo" "freedom"
</syntaxhighlight>
</lang>
 
Filter and map:
 
<syntaxhighlight lang=R>
<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>
</lang>
 
=={{header|Racket}}==
<langsyntaxhighlight lang=racket>
#lang racket
(define (fold f xs init)
Line 2,502:
 
(fold + '(1 2 3) 0) ; the result is 6
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
Line 2,508:
{{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 perl6line>my @list = 1..10;
say [+] @list;
say [*] @list;
Line 2,514:
say min @list;
say max @list;
say [lcm] @list;</langsyntaxhighlight>
{{out}}
<pre>55
Line 2,523:
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 perl6line>my @list = 1..10;
say reduce &infix:<+>, @list;
say reduce &infix:<*>, @list;
Line 2,529:
say reduce &infix:<min>, @list;
say reduce &infix:<max>, @list;
say reduce &infix:<lcm>, @list;</langsyntaxhighlight>
 
=={{header|REXX}}==
Line 2,537:
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.
<langsyntaxhighlight 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 'list:' fold(@list, "list")
Line 2,575:
x= x*! / GCD(x, !) /*GCD does the heavy work*/
end /*k*/
return x</langsyntaxhighlight>
{{out|output|:}}
<pre>
Line 2,590:
 
=={{header|Ring}}==
<langsyntaxhighlight lang=ring>
n = list(10)
for i = 1 to 10
Line 2,625:
if op = "cat" decimals(0) cat = string(n[1])+cat2 ok
return cat
</syntaxhighlight>
</lang>
 
=={{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 2,645:
# [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 2,675:
if op$ = "avg" then cat = cat / count
if op$ = "cat" then cat = val(str$(n(1))+cat$)
end function</langsyntaxhighlight>
<pre> +: 55
-: -53
Line 2,688:
=={{header|Rust}}==
 
<langsyntaxhighlight lang=rust>fn main() {
println!("Sum: {}", (1..10).fold(0, |acc, n| acc + n));
println!("Product: {}", (1..10).fold(1, |acc, n| acc * n));
Line 2,694:
println!("Concatenation: {}",
chars.iter().map(|&c| (c as u8 + 1) as char).collect::<String>());
}</langsyntaxhighlight>
 
{{out}}
Line 2,704:
 
=={{header|Scala}}==
<langsyntaxhighlight lang=scala>object Main extends App {
val a = Seq(1, 2, 3, 4, 5)
println(s"Array : ${a.mkString(", ")}")
Line 2,712:
println(s"Minimum : ${a.min}")
println(s"Maximum : ${a.max}")
}</langsyntaxhighlight>
 
=={{header|Scheme}}==
===Implementation===
reduce implemented for a single list:
<langsyntaxhighlight lang=scheme>(define (reduce fn init lst)
(do ((val init (fn (car rem) val)) ; accumulated value passed as second argument
(rem lst (cdr rem)))
Line 2,723:
 
(display (reduce + 0 '(1 2 3 4 5))) (newline) ; => 15
(display (reduce expt 2 '(3 4))) (newline) ; => 262144</langsyntaxhighlight>
===Using SRFI 1===
There is also an implementation of fold and fold-right in SRFI-1, for lists.
Line 2,747:
 
=={{header|Sidef}}==
<langsyntaxhighlight lang=ruby>say (1..10 -> reduce('+'));
say (1..10 -> reduce{|a,b| a + b});</langsyntaxhighlight>
 
=={{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}}==
<langsyntaxhighlight 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) }))</langsyntaxhighlight>
 
{{out}}
Line 2,772:
=={{header|Tailspin}}==
It is probably easier to just write the whole thing as an inline transform rather than create a utility.
<langsyntaxhighlight lang=tailspin>
[1..5] -> \(@: $(1); $(2..last)... -> @: $@ + $; $@!\) -> '$;
' -> !OUT::write
Line 2,779:
[1..5] -> \(@: $(1); $(2..last)... -> @: $@ * $; $@!\) -> '$;
' -> !OUT::write
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,788:
 
If you really want to make a utility, it could look like this:
<langsyntaxhighlight lang=tailspin>
templates fold&{op:}
@: $(1);
Line 2,808:
[1..5] -> fold&{op:mul} -> '$;
' -> !OUT::write
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,817:
=={{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 2,823:
}
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 2,837:
</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.
 
Line 2,845:
{{trans|FreeBASIC}}
uBasic/4tH has only got one single array so passing its address makes little sense. Instead, its bounds are passed.
<syntaxhighlight lang=text>Push 5, 4, 3, 2, 1: s = Used() - 1
For x = 0 To s: @(x) = Pop(): Next
 
Line 2,871:
_multiply Param (2) : Return (a@ * b@)
_max Param (2) : Return (Max(a@, b@))
_min Param (2) : Return (Min(a@, b@))</langsyntaxhighlight>
{{out}}
<pre>Sum is : 15
Line 2,884:
 
=={{header|VBA}}==
<langsyntaxhighlight lang=vb>Public Sub reduce()
s = [{1,2,3,4,5}]
Debug.Print WorksheetFunction.Sum(s)
Debug.Print WorksheetFunction.Product(s)
End Sub</langsyntaxhighlight>
 
=={{header|Vlang}}==
{{trans|go}}
<langsyntaxhighlight lang=vlang>vfn main() {
n := [1, 2, 3, 4, 5]
Line 2,910:
}
return r
}</langsyntaxhighlight>
 
{{out}}
Line 2,922:
Translated from the JavaScript ES6 example with a few modifications.
 
<langsyntaxhighlight lang=WDTE>let a => import 'arrays';
let s => import 'stream';
let str => import 'strings';
Line 2,934:
 
# And here's a concatenation:
s.range 1 11 -> s.reduce '' (str.format '{}{}') -- io.writeln io.stdout;</langsyntaxhighlight>
 
=={{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}}
Line 2,948:
 
=={{header|Wren}}==
<langsyntaxhighlight lang=ecmascript>var a = [1, 2, 3, 4, 5]
var sum = a.reduce { |acc, i| acc + i }
var prod = a.reduce { |acc, i| acc * i }
Line 2,955:
System.print("Sum is %(sum)")
System.print("Product is %(prod)")
System.print("Sum of squares is %(sumSq)")</langsyntaxhighlight>
 
{{out}}
Line 2,967:
=={{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}}
<langsyntaxhighlight lang=zxbasic>10 DIM a(5)
20 FOR i=1 TO 5
30 READ a(i)
Line 2,987:
1030 LET tmp=VAL ("tmp"+o$+"a(i)")
1040 NEXT i
1050 RETURN </langsyntaxhighlight>
10,327

edits