
Am Montag 30 März 2009 06:37:57 schrieb Zachary Turner:
On Sun, Mar 29, 2009 at 6:47 PM, Daniel Fischer
wrote: The &&& operator is pretty sweet, thanks for pointing it out. That's pretty much what I was trying to come up with the mapping and mapping2,
Yep. Pretty good thinking, by the way.
but it's more general and hence more useful.
More general doesn't necessarily imply more useful, specialisation can sometimes be necessary for performance reasons. A big advantage of (&&&) and friends is that many Haskellers know them and won't need to look up the definitions when reading your code, as would be necessary if you use your own differently named variant. So if you come up with with generally useful patterns like (|>), mapping and mapping2, find out whether it's already defined in a library. Try searching for the type in Hoogle, and if it doesn't find it, ask on the list.
The "pipelining" operator I defined should definitely be used with care. For example, it requires the pipelined argument to be the last argument, which is not always the case.
It's the same for ($) and (.). If your pipeline is too complicated to write it with (|>) and a few flips, you should probably write it in a different style anyway.
And I've also found that with it I tend to think about the problem less, and write less efficient code as a result. For example given a list of integers, an easy and very readable way to remove all multiples of 2 from a list, and then double the remaining items could be like this:
let doit x = x |> filter (\y -> y `mod` 2 == 0) |> map (* 2)
as opposed to the more efficient
doit [] = [] doit (x:xs) | (x `mod` 2 == 0) = doit xs doit (x:xs) = (2 * x) : doit xs
since the list is walked twice.
No, thanks to laziness, it's only walked once, the intermediate list won't ever be constructed. If there's any performance difference, it should be minuscule.
(I'm betting someone will respond with a cool one-liner here involving function composition or something else that I can't think of yet :)
list comprehension: doit x = [2*y | y <- x, even y] function composition: doit = map (*2) . filter even doit = filter even >>> map (*2) If you use one of the latter two, be sure to give a type signature, or you'll probably be bitten by the monomorphism restriction.