I am looking for list utilities that may aid me in using more functional programming paradigms in Perl. I find myself writing many of these often, so I was wondering if there was already a CPAN module to help me. I tried searching Perlmonks (and CPAN) for related questions, but I was unsuccessful in my attempt.
It seems that many people here swear by List:Util and List::MoreUtils. (There must be more! I'm sorry I was unable to find them.) However, there are still many functions that I would like to use:
- transpose LIST-OF-LISTS which turns ([1,2,3],[2,3,5]) into ([1,2],[2,3],[4,5]). Notice that List::MoreUtils::zip does not do what I want.
- multimap BLOCK LIST, LIST, ... which applies BLOCK (or a function, like the usual map) element-wise to the LISTs (the BLOCK would get as many arguments as there are lists, and each list must be the same length).
At this point, I pause to note that Perl's calling mechanism does not make such a function easy (probably one reason why I can't seem to find such a function). As such, there are a couple approaches to the problem. Suppose we have two lists
@a and
@b and we wish to create
($a[0]+$b[0], $a[1]+$b[1], ...); then we could (a) use
transpose something like
map { $$_[0] + $$_[1] } transpose @a, @b or (b) supply list references (my preferred approach)
multimap { $_[0] + $_[1] } [1,2,3], [2,3,5]. Notice that
List::MoreUtils::pairwise does the two-list version of what I want here. From now on, assume LIST means a list reference.
- append LIST, LIST, ... which appends the lists. The two version case is something like sub append { [@{$_[0]}, @{$_[1]}] } (or your favorite version of push, etc), but this should work for an arbitrary number of lists (note: Mathematica calls this function Flatten). Easy to implement using one call to reduce from List::MoreUtils, or alternatively a short block of code? Probably, but see both my next function and my comment at the end.
- fold_left BLOCK INITIAL, LIST which starting with INITIAL, applies BLOCK in a left-associative fashion to LIST. Yup, just like reduce, except it has an initial value; some other functions should have this property, like sum of an empty list should really be zero. (I state that from a mathematical standpoint.)
- fold_right similarly. Reverse twice? Yeah, I know, but sometimes you just want another function.
- mult. So there's a sum, but no mult? What's up with that? In general, in Perl, is there a way to call * (multiplication) something like main::*( 2, 3 ) (preferably with arbitrarily many arguments, as in dialects of Lisp, but two is fine). This would make negation of every element of a list very easy, something like map main::unary_minus, LIST. It might also make the following two functions easier.
- Other Mathematica functions like Inner, Outer, Tuples, as well as cross-products and such.
So you say all of these are easy to implement from scratch or by using List::MoreUtils? Perhaps, but I was looking for an existing implementation, perhaps implemented in XS for efficiency. If there is no such thing, would people be interested in such a CPAN module (unfortunately, I probably wouldn't be able to do an XS version myself)? Thanks for your help!
Remark: I have likely mixed the uses of "array" and "list" in this node. However, I do not think it matters here, really, because I would really like for all of these functions to work on list references. In particular, my preferred example for transpose is "[[1,2,3],[2,3,5]] into [[1,2],[2,3],[4,5]]."
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.