[Haskell-beginners] numerical types, the $ operator
daniel.is.fischer at web.de
Mon Mar 30 06:21:50 EDT 2009
Am Montag 30 März 2009 06:37:57 schrieb Zachary Turner:
> On Sun, Mar 29, 2009 at 6:47 PM, Daniel Fischer
<daniel.is.fischer at web.de>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 :)
doit x = [2*y | y <- x, even y]
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.
More information about the Beginners