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.

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.

+4
A:

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

trinithis
2010-07-04 18:17:26

+11
A:

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)
```

Carl
2010-07-04 18:22:27

I refer to this as "opaque haskell".At a certain point it's just illegible, the point varies on exposure.

Dan
2010-07-04 18:58:47
In fact, I tend to define a function which, for lack of a better name, I call `preserving :: (a -> b) -> a -> (a,b)`, defined as simply `preserving = (id I ought to be consistent.) I'm always a little surprised that it doesn't seem to exit anywhere standard.

Antal S-Z
2010-07-04 19:51:59
Dan, I think that's probably the easiest Arrow combinator to use in real code. Its name is nicely evocative: you can read that line of code out loud as "map id and sqrt to xs".

Carl
2010-07-04 20:08:59
+11
A:

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
```

danlei
2010-07-04 18:23:27

+7
A:

I would probably write `map`

/`zip`

and then later wish I had written the list comprehension.

Norman Ramsey
2010-07-05 02:50:06

+5
A:

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
```

MtnViewMark
2010-07-05 03:46:27

+1
A:

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?")

BMeph
2010-07-05 05:48:45

+2
A:

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)
```

Greg Bacon
2010-07-08 18:20:13