Tim Coulter
Tim Coulter

Reputation: 9

List comprehension troubles

I want to use a list comprehension to have a string if a certain condition is true but if the condition is not true then put the empty string in (or empty list).

for example : [ Bob | i <- [3..6], i == 4 ] this gives the list ["Bob"] but I want to get: [ "" , "Bob" , "" , "" ] so any empty string whenever i does not equal 4.

Is it possible to do this within a list comprehension.

Upvotes: 0

Views: 149

Answers (4)

fp_mora
fp_mora

Reputation: 714

There is nothing wrong with what you have. It's just you have to force the result whether it meets the condition or doesn't. The way to do that is to put what you have in a list comprehension and have it "execute" a number of times.

[ concat ["Bob" | x == 4] | x <- [3..6] ]

The condition of x not equal 4 produces and empty list '[]' so concat converts them to identical strings for list uniformity.

Upvotes: -2

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477676

The reason this does not work is because you use i == 4 as a filter:

[ "Bob" | i <- [3..6], i == 4  ]
--                     ^ filter

So that means that only in case i == 4, you will add "Bob" to the list. In case the condition was True for instance two times (for example i < 5), then we would yield "Bob" twice.

The condition is not a filter: it determines what should be added to the list, not on what condition something should be added. In that case you can use function that checks the condition, and returns different results.

We can use bool :: a -> a -> Bool -> a for this (this is a catamoprhism over Bool):

import Data.Bool(bool)

[ bool "" "Bob" (i == 4) | i <- [3..6] ]

Note that we can use map as well:

import Data.Bool(bool)

map (bool "" "Bob" . (4 ==)) [3..6]

Upvotes: 3

Adam Smith
Adam Smith

Reputation: 54243

Use an if construction.

[ if i == 4 then "Bob" else "" | i <- [3..6] ]

Though this is probably better without a list comprehension

map f [3..6]
  where
  f 4 = "Bob"
  f _ = ""

Upvotes: 4

madgen
madgen

Reputation: 747

Left side of the pipe does not have to be a value. You can do it like this: [ if i == 4 then "Bob" else "" | i <- [3..6]].

Upvotes: 3

Related Questions