Pergunta

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.

Foi útil?

Solução

I'd likely write

map (\x -> (x, sqrt x)) xs

If you prefer point-free, the above is equivalent to (after having imported Control.Monad and Control.Monad.Instances)

map (ap (,) sqrt) xs

Another alternative that hasn't yet been mentioned is

zipWith (,) xs (map sqrt xs)

Outras dicas

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.

For certain types of problems (Project Euler in particular), this particular case comes up so often that I wrote the following little helper:

with :: (a -> b) -> a -> (a,b)
with f a = (a, f a)

This allows your example to be written:

r = map (with sqrt) xs

I'm more of an "Old School" Haskellier, so I'd use zip `ap` map sqrt and later refactor it to use the <*> instead of ap.

Applicative is the new Monad. (In the sense of "what do the Cool Haskell Kids use these days?")

I rarely use list comprehensions, but both are dandy. Just use the one that makes your code easier to read.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top