Which of the following are you most likely to write?
r = zip xs $ map sqrt xs
or
r = [(x, sqrt x) | x <- xs]
Sample code on the Internet seems to indicate that the former is more abundant and the preferred way.
People who spend too much time in #haskell would probably write that as
r = map (id &&& sqrt) xs
(&&&)
is a fun combinator defined in Control.Arrow
. Its actual type signature is complicated because it's generalized to all instances of Arrow. But it's often used with the (->)
instance of Arrow
, which results in this type signature:
(&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)
Although I tend to not use them very often, in this case, I think I'd prefer the list comprehension version, since it seems cleaner to me.
If you're into point free style, you might like this one, too:
f = zip `ap` map sqrt
ap lives in Control.Monad and in this case, it can be thought of as the S combinator, which generalizes application in SKI calculus:
ap f g x == f x (g x)
ap const const == id
As Conal points out, this may also be generalized from Monad to Applicative thusly (import Control.Applicative):
f = zip <*> map sqrt
I would probably write map
/zip
and then later wish I had written the list comprehension.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With