Zulraidur
Zulraidur

Reputation: 41

Using variables in parallel list comprehensions in Haskell

In a parallel list comprehension in Haskell, I encounter a problem when trying to use a guard.

largestPalindrome :: Int -> Int
largestPalindrome x = maximum [ a*b
                              | a <- [x,x-1..1]
                              | b <- [x,x-1..1]
                              , isPalindrome (a*b) ]

The error that is displayed is

Variable not in scope: a :: Int

Upvotes: 4

Views: 742

Answers (1)

Alec
Alec

Reputation: 32309

Quoted from Haskell Prime:

Parallel comprehensions extend list comprehensions with a notation for zips. The comprehension

[ e | quals1 | ... | qualsN ]

can be desugared to

zipWithN (\ p1 ... pN -> e) [p1 | quals1] ... [pN | qualsN]

where pi is a tuple of the variables defined by qualsi and used by e.

So, from your example, [a*b |a<- [x,x-1..1] | b <- [x,x-1..1] , isPalindrome (a*b)] is roughly equivalent to

zipWith (\a b -> a*b)
        [ a | a<-[x,x-1..1] ]
        [ b | b <- [x,x-1..1], isPalindrome (a*b) ]

where it is pretty clear why a is not in scope for the last list comprehension. Intuitively, you should think of each | delimited part as being completely independent from the others. Any filtering operation is going to be bound to only one of these parts.

Upvotes: 6

Related Questions