preferred_anon
preferred_anon

Reputation: 547

Double List Comprehension in Haskell

I'm trying to implement an array as a list of lists in Haskell. In particular, I have some array m that I'm given, and a predicate p that I want to be satisfied, and I want to create a list of indices (x,y) such that the xth element of the yth list satisfies p. I set this up as the following list comprehension:

[(x,y) | x<-[1..],y<-[1..],p ((m !! y) !! x)]  

Which throws up an error when it tries to find an element of m in the first row that doesn't exist. I can see one immediate way to fix this is to just change the inner comprehensions on x and y to something like y<-[1..length m] but I feel like there's a cuter way that exploits laziness. I just don't know what it is.

Upvotes: 2

Views: 2381

Answers (1)

&#216;rjan Johansen
&#216;rjan Johansen

Reputation: 18199

Indeed there is. The common idiom for getting list elements together with their indices is to use zip:

[(x,y) | (x,mx) <- zip [1..] m, (y,mxy) <- zip [1..] mx, p mxy]

Also:

  • !! is quite inefficient, especially when extracting many elements from a list, so it's best to try to avoid it when possible.
  • List indices usually start with 0 in Haskell.

Upvotes: 6

Related Questions