So, for example, say I had a list of numbers and I wanted to create a list that contained each number multiplied by 2 and 3. Is there any way to do something like the following, but get back a single list of numbers instead of a list of lists of numbers?
mult_nums = [ [(n*2),(n*3)] | n <- [1..5]]
-- this returns [[2,3],[4,6],[6,9],[8,12],[10,15]]
-- but we want [2,3,4,6,6,9,8,12,10,15]
List comprehension in Haskell is a way to produce the list of new elements from the generator we have passed inside it. Also for the generator values, we can apply the Haskell functions to modify it later. This list comprehension is very y easy to use and handle for developers and beginners as well.
But in Haskell, you only need to allocate space for the items in the list that actually get evaluated. The two most basic functions for creating an infinite list are "repeat" and "cycle". The first makes an infinite number of the same element, while the second allows you to cycle through a specific series of elements.
Finding / searching 0 will result in 1 . (Related: head xs returns the first element of the list.) (Related: last xs returns the last element of the list.)
I find that extending the list comprehension makes this easier to read:
[ m | n <- [1..5], m <- [2*n,3*n] ]
It might be helpful to examine exactly what this does, and how it relates to other solutions. Let's define it as a function:
mult lst = [ m | n <- lst, m <- [2*n,3*n] ]
After a fashion, this desugars to
mult' lst =
concatMap (\n -> concatMap (\m -> [m]) [2*n,3*n]) lst
The expression concatMap (\m -> [m])
is wrapping m
up in a list in order to immediately flatten it—it is equivalent to map id
.
Compare this to @FunctorSalad's answer:
mult1 lst = concatMap (\n -> [n*2,n*3]) lst
We've optimized away concatMap (\m -> [m])
.
Now @vili's answer:
mult2 lst = concat [ [(n*2),(n*3)] | n <- lst]
This desugars to:
mult2' lst = concat (concatMap (\n -> [[2*n,3*n]]) lst)
As in the first solution above, we are unnecessarily creating a list of lists that we have to concat
away.
I don't think there is a solution that uses list comprehensions, but desugars to mult1
. My intuition is that Haskell compilers are generally clever enough that this wouldn't matter (or, alternatively, that unnecessary concat
s are cheap due to lazy evaluation (whereas they're lethal in eager languages)).
you could use concat.
concat [ [(n*2),(n*3)] | n <- [1..5]]
output: [2,3,4,6,6,9,8,12,10,15]
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