
quoth Mateusz Kowalczyk
Also I wonder if laziness saves us here: in the original program we effectively do map and filter at the same time. If we were to take (catMaybes . map f) with strict evaluation then we'd be traversing twice: once to map and once to catMaybes… Just something to think about, I think performance would be no worse anyway, at least not by much.
Might be right, I really have little idea what's going on underneath there - I'd have guessed that lazy or not, the two functions are doing all the work of traversing their separate lists even if at any conceptual moment those lists are nothing but a head and a tail. The rationale is mostly about a cleaner presentation. I was thinking of this problem a few weeks back when we were talking about C programmers learning Haskell. I'd guess they'd find a certain lack of elegance in the Maybe strategy, compared to what would be a pretty simple and direct problem in C, like "for (i = j = 0; i < n; ++i) if (toChar(vx[i], &cx[j]) ++j;" The recursive function I wrote for reference is my least favorite solution, less clear and more prone to stupid coding errors. If my list comprehension idea had been valid, I think it would have been a very concise presentation.
... in this case I don't think we're desperate enough to use a nonstandard extension.
I wouldn't worry about using a ‘non-standard’ extension: you're probably not going to stick to H98 or H2010 in non-trivial programs either way. LambaCase is just a trivially expandable sugar anyway, modulo clean identifier name.
I do make frequent use of ForeignFunctionInterface, but perhaps that's the exception that proves the rule inasmuch as it has little to do with the language per se. I'm happy that I don't have to deal with programs that couldn't have been written without extensions. Donn