3

I just started learning Haskell and I started looking into understanding comprehension which allows me to form a subset by giving conditions to a bigger set.

I tried to make a comprehension that takes a nested list (containing other integer lists) and removes all the positive odd numbers from them and empty inner lists.

testList= [-3]:[-5,8]:[[1,3,5,7,9],[],[4,6,8,10],[1,3,6,7,9],[],[1]]

removingOnlyPosOdds xxs = [ [x | x <-xs, not (odd x && x > 0 )] | xs <- xxs, [] /= xs ] 

testList before applying the comprehension function on it looked like:

[[-3],[-5,8],[1,3,5,7,9],[],[4,6,8,10],[1,3,6,7,9],[],[1]]

After applying removingOnlyPosOdds testList

The outcome was 
[[-3],[-5,8],[],[4,6,8,10],[6],[]] 

So what I realised that "[] /= xs" in the function description was removing the already existent

"[]" inner lists in testList only; but not the new ones that were formed caused by me removing positive odd numbers from the inner lists.

What should be my next step in order to remove those as well code wise?

I want it to look like

[[-3],[-5,8],[4,6,8,10],[6]]

Is there a way to generalise the comprehension to do it in one go?

Or is there another approach which would be much better to deal with the removal of things (like the empty inner lists )and to make a more specified set?

1 Answer 1

3

You can add some extra filtering, and prevent doing the same list comprehension twice with a let clause, like:

removingOnlyPosOdds xxs = [ ys | xs <- xxs, let ys = [x | x <-xs, not (odd x && x > 0 )], not (null ys)  ]

Or we can just add some extra filtering, like:

removingOnlyPosOdds :: Integral i => [[i]] -> [[i]]
removingOnlyPosOdds = filter (not . null) . map (filter (\x -> not (odd x && x > 0)))

or even more pointfree:

import Control.Monad(liftM2)

removingOnlyPosOdds :: Integral i => [[i]] -> [[i]]
removingOnlyPosOdds = filter (not . null) . map (filter (not . liftM2 (&&) odd (>0)))

For example:

Prelude> removingOnlyPosOdds [[-3],[-5,8],[1,3,5,7,9],[],[4,6,8,10],[1,3,6,7,9],[],[1]]
[[-3],[-5,8],[4,6,8,10],[6]]
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.