You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A very common operation is to map a n-adic function (like a triadic one) on n iterables. To do it in Haskell you use zipWith, example:
Prelude> let arr1 = [1, 2, 3]
Prelude> let arr2 = [10, 20, 30]
Prelude> let arr3 = [100, 200, 300]
Prelude> let foo x y z = x + y * z
Prelude> zipWith3 foo arr1 arr2 arr3
[1001,4002,9003]
In Python2.6 the normal map function is enough, it optionally accepts more than one iterable (in Python3 map does the same, but it's lazy):
def foo(x, y, z):
return x + y * z
arr1 = [1, 2, 3]
arr2 = [10, 20, 30]
arr3 = [100, 200, 300]
print map(foo, arr1, arr2, arr3)
But in D2+Phobos you need to write awkward code:
import std.stdio, std.algorithm, std.range;
int foo(int x, int y, int z) {
return x + y * z;
}
void main() {
auto arr1 = [1, 2, 3];
auto arr2 = [10, 20, 30];
auto arr3 = [100, 200, 300];
auto r = map!((t){ return foo(t.tupleof); })(zip(arr1, arr2, arr3));
writeln(r);
}
Output:
[1001, 4002, 9003]
Unlike Python currently std.algorithm.map() is designed to optionally accept more than one function, and return a tuple. It's sometimes useful to do this, but in my experience the semantics of the Python map is useful more often. So I'd like the semantics of D map to become similar to the semantics of the Python3 map. In this case the D code becomes something like:
auto r = map!foo(arr1, arr2, arr3);
If this is not possible, or not desired (or it leads to too much complex Phobos code), then I suggest to introduce a new function in std.algorithm (or even in std.range) that acts like the Haskell zipWith. In this case the D code becomes something like:
auto r = zipWith!foo(arr1, arr2, arr3);
The text was updated successfully, but these errors were encountered:
An example usage for triadic map/zipWith (this is Euler problem 18, http://projecteuler.net/index.php?section=problems&id=18 ):
import std.stdio, std.algorithm, std.range, std.array;
auto reversed(R)(R range) {
auto result = array(range);
result.reverse;
return result;
}
int f(int x, int y, int z) { return x + max(y, z); }
int[] g(int[] xs, int[] ys) {
return array(map!((t){ return f(t.tupleof); })(zip(ys, xs[0..$-1], xs[1..$])));
}
void main() {
auto tri = [[75],
[95,64],
[17,47,82],
[18,35,87,10],
[20, 4,82,47,65],
[19, 1,23,75, 3,34],
[88, 2,77,73, 7,63,67],
[99,65, 4,28, 6,16,70,92],
[41,41,26,56,83,40,80,70,33],
[41,48,72,33,47,32,37,16,94,29],
[53,71,44,65,25,43,91,52,97,51,14],
[70,11,33,28,77,73,17,78,39,68,17,57],
[91,71,52,38,17,14,91,43,58,50,27,29,48],
[63,66, 4,68,89,53,67,30,73,16,69,87,40,31],
[ 4,62,98,27,23, 9,70,98,73,93,38,53,60, 4,23]];
writeln(reduce!g(reversed(tri))[0]);
}
In Haskell it becomes:
problem_18 = head $ foldr1 g tri
where
f x y z = x + max y z
g xs ys = zipWith3 f xs ys $ tail ys
tri = [...]
In Python2.6 (this is not pythonic code):
f = lambda x, y, z: x + max(y, z)
g = lambda xs, ys: map(f, ys, xs[:-1], xs[1:])
print reduce(g, reversed(tri))[0]
With a n-way map the function g() becomes (this uses the array version of map):
int[] g(int[] xs, int[] ys) {
return amap!f(ys, xs[0..$-1], xs[1..$]);
}
With a zipWith the function g() becomes:
int[] g(int[] xs, int[] ys) {
return array(zipWith!f(ys, xs[0..$-1], xs[1..$]));
}
bearophile_hugs reported this on 2011-05-18T18:20:16Z
Transfered from https://issues.dlang.org/show_bug.cgi?id=6034
CC List
Description
The text was updated successfully, but these errors were encountered: