Skip to content

ParallelListComp semantics differs from the documented one

The desugaring of parallel list comprehensions described in the manual appears to state that parallel bars (|) have higher precedence than what comes after them, but this is not how they work in practice.

Example 1

{-# LANGUAGE ParallelListComp #-}

main = print
  [ (a, b)
  | a <- [1 .. 5]
  | b <- [1 .. 5]
  , b >= 4
  ]

The desugaring implied by the docs is

main = print
  [ (a, b)
  | (a, b) <- zip [1 .. 5] [1 .. 5]
  , b >= 4
  ]

so I'd expect the result to be [(4,4),(5,5)]. Yet the actual result is [(1,4),(2,5)], showing that the comma has higher precedence here.

Example 2

{-# LANGUAGE ParallelListComp #-}

main = print
  [ (a, b)
  | a <- [1 .. 5]
  | b <- [1 .. 5]
  , a >= 4
  ]

Result:

parlistcomp.hs:7:5: error:
    • Variable not in scope: a :: Integer
    • Perhaps you meant ‘a’ (line 5)
  |
7 |   , a >= 4
  |     ^

Again, this is consistent with the comma binding more tightly than the bar. But also notice that ghc itself is confused about the scoping rules: it says a is not in scope, yet suggests a as a valid replacement.

Environment

  • GHC version used: 8.6.5, 8.8.1
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information