digitalmars.D.bugs - [Issue 7957] New: std.functional untuple/untupleReversed too
- d-bugmail puremagic.com (86/86) Apr 20 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7957
http://d.puremagic.com/issues/show_bug.cgi?id=7957 Summary: std.functional untuple/untupleReversed too Product: D Version: D2 Platform: All OS/Version: All Status: NEW Severity: enhancement Priority: P2 Component: Phobos AssignedTo: nobody puremagic.com ReportedBy: bearophile_hugs eml.cc I suggest two functions like this in Phobos. Maybe a more correct name for them is apply/applyReversed, but apply() is probably meant to be more flexible. The purpose of untuple is to apply the items of a tuple as arguments to a function, inside map/filter. So instead of this: t => foo2(t.tupleof) You write a less complex: untuple!foo2 Python has the itertools.starmap function to perform a lazy map with untuple (apply) too, but it lacks a starfilter: http://docs.python.org/library/itertools.html#itertools.starmap untupleReversed does a little more, because it also reverses the tuple items before feeding them to the foo2 function. This is often useful for 2-tuples, it's related to (but not the same as) the "flip" function used in Haskell: -- | 'flip' f takes its (first) two arguments in the reverse order of f . flip :: (a -> b -> c) -> b -> a -> c flip f x y = f y x It's an "adapter" between a range of tuples and an already written function that takes flipped or reversed arguments. - - - - - - - - - - - - - - - - - - - - - - - - - - - - import std.algorithm, std.range, std.stdio, std.functional, std.typecons, std.traits; // To apply a given callable to a Tuple (alternative name: "apply"). template untuple(alias callable) { auto untuple(Tup)(Tup t) if (isTuple!Tup && ParameterTypeTuple!callable.length == Tup.length) { return callable(t.tupleof); } } void main() { auto a1 = "abcd"d; auto a2 = [10, 20, 30, 40]; auto a3 = [100, 200, 300, 400]; static int foo2(dchar a, int b) { return a + b; } zip(a1, a2).map!(t => foo2(t.tupleof))().writeln(); zip(a1, a2).map!(untuple!foo2)().writeln(); static int foo3(dchar a, int b, int c) { return a + b + c; } zip(a1, a2, a3).map!(untuple!foo3)().writeln(); } Output: [107, 118, 129, 140] [107, 118, 129, 140] [207, 318, 429, 540] - - - - - - - - - - - - - - - - - - - - - - - - - - - - One version that also reverses the tuple items: import std.algorithm, std.range, std.stdio, std.typecons, std.traits, std.typetuple, std.string, std.conv; // _genIndexes("foo", 3) ==> "foo[2], foo[1], foo[0]" private string _genIndexes(string name, size_t start) { string[] result; for (int i = start - 1; i >= 0; i--) result ~= name ~ "[" ~ text(i) ~ "]"; return result.join(", "); } // To apply a given callable to a Tuple (alternative name: "apply"), // but flipping the tuple items. template untupleReversed(alias callable) { auto untupleReversed(Tup)(Tup t) if (isTuple!Tup && ParameterTypeTuple!callable.length == Tup.length) { mixin("return callable(" ~ _genIndexes("t", Tup.length) ~ ");"); } } void main() { auto pairs = zip([10, 20, 30, 40], [100, 200, 300, 400]); static int div2(int a, int b) { return a / b; } pairs.map!(t => div2(t[1], t[0]))().writeln(); pairs.map!(untupleReversed!div2)().writeln(); } Output: [10, 10, 10, 10] [10, 10, 10, 10] -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 20 2012