Catamorphism: Difference between revisions
(added ocaml) |
|||
Line 93: | Line 93: | ||
say reduce &infix:<lcm>, @list;</lang> |
say reduce &infix:<lcm>, @list;</lang> |
||
=={{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)). |
|||
% foldl is now a predicate of SWI-Prolog 6.3.1 |
|||
% |
|||
catamorphism :- |
|||
numlist(1,10,L), |
|||
foldl(\XS^YS^ZS^(ZS is XS+YS), L, 0, Sum), |
|||
format('Sum of ~w is ~w~n', [L, Sum]), |
|||
foldl(\XP^YP^ZP^(ZP is XP*YP), L, 1, Prod), |
|||
format('Prod of ~w is ~w~n', [L, Prod]), |
|||
string_to_list(LV, ""), |
|||
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]). |
|||
</lang> |
|||
Output : |
|||
<pre> ?- catamorphism. |
|||
Sum of [1,2,3,4,5,6,7,8,9,10] is 55 |
|||
Prod of [1,2,3,4,5,6,7,8,9,10] is 3628800 |
|||
Concat of [1,2,3,4,5,6,7,8,9,10] is 12345678910 |
|||
true. |
|||
</pre> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
<lang python>>>> from operator import add |
<lang python>>>> from operator import add |
Revision as of 21:04, 1 October 2012
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.
Show how reduce (or foldl or foldr etc), work in your language.
- Cf.
C#
<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>
D
<lang d>import std.stdio, std.algorithm, std.range, std.numeric,
std.conv, std.typecons, std.typetuple;
void main() {
auto list = iota(1, 11); alias TypeTuple!(q{a + b}, q{a * b}, min, max, gcd) ops;
foreach (op; ops) writeln(op.stringof, ": ", list.reduce!op());
// std.algorithm.reduce supports multiple functions in parallel: reduce!(ops[0], ops[3], text)(tuple(0, 0.0, ""), list).writeln();
}</lang>
- Output:
"a + b": 55 "a * b": 3628800 min(T1,T2,T...) if (is(typeof(a < b))): 1 max(T1,T2,T...) if (is(typeof(a < b))): 10 gcd(T): 1 Tuple!(int,double,string)(55, 10, "12345678910")
JavaScript
<lang javascript>var nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
function add(a, b) {
return a + b;
}
var summation = nums.reduce(add);
function mul(a, b) {
return a * b;
}
var product = nums.reduce(mul, 1);
var concatenation = nums.reduce(add, "");
console.log(summation, product, concatenation);</lang>
OCaml
<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 ( * ) 0 nums;;
val product : int = 0</lang>
Perl 6
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. <lang perl6>my @list = 1..10; say [+] @list; say [*] @list; say [~] @list; say [min] @list; say [max] @list; say [lcm] @list;</lang>
- Output:
55 3628800 12345678910 1 10 2520
In addition to the reduce metaoperator, a general higher-order function, reduce, 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; say reduce &infix:<*>, @list; say reduce &infix:<~>, @list; say reduce &infix:<min>, @list; say reduce &infix:<max>, @list; say reduce &infix:<lcm>, @list;</lang>
Prolog
SWI-Prolog has native foldl in version 6.3.1
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)).
% foldl is now a predicate of SWI-Prolog 6.3.1 % catamorphism :- numlist(1,10,L), foldl(\XS^YS^ZS^(ZS is XS+YS), L, 0, Sum), format('Sum of ~w is ~w~n', [L, Sum]), foldl(\XP^YP^ZP^(ZP is XP*YP), L, 1, Prod), format('Prod of ~w is ~w~n', [L, Prod]), string_to_list(LV, ""), 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]). </lang> Output :
?- catamorphism. Sum of [1,2,3,4,5,6,7,8,9,10] is 55 Prod of [1,2,3,4,5,6,7,8,9,10] is 3628800 Concat of [1,2,3,4,5,6,7,8,9,10] is 12345678910 true.
Python
<lang python>>>> from operator import add >>> listoflists = [['the', 'cat'], ['sat', 'on'], ['the', 'mat']] >>> help(reduce) Help on built-in function reduce in module __builtin__:
reduce(...)
reduce(function, sequence[, initial]) -> value Apply a function of two arguments cumulatively to the items of a sequence, from left to right, so as to reduce the sequence to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). If initial is present, it is placed before the items of the sequence in the calculation, and serves as a default when the sequence is empty.
>>> reduce(add, listoflists, []) ['the', 'cat', 'sat', 'on', 'the', 'mat'] >>> </lang>
Additional example
<lang python>from functools import reduce from operator import add, mul
nums = range(1,11)
summation = reduce(add, nums)
product = reduce(mul, nums)
concatenation = reduce(lambda a, b: str(a) + str(b), nums)
print(summation, product, concatenation)</lang>