Haskell parallel and generalized (SQL-like) list comprehension problem
Maybe I'm misreading the docs (http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/syntax-extns.html#parallel-list-comprehensions) but in the following code I'd expect the list comprehe开发者_StackOverflow社区nsions zs and zs' to have the same value. However, they are different, as shown by main printing two different lines:
{-# LANGUAGE ParallelListComp, TransformListComp #-}
import GHC.Exts
xs = [10,20..90]
ys = map (`mod`7) xs
zs = [(x,y) | x<-xs | y<-ys, then sortWith by y]
zs' = [(x,y) | (x,y) <- zip xs ys, then sortWith by y]
main = print zs >> print zs'
Am I simply misreading the docs, or is there some worse problem? I'm surprised the type system didn't catch the error in the actual code this was abstracted from.
This output is produced:
*Main> main
[(10,0),(20,1),(30,2),(40,3),(50,3),(60,4),(70,5),(80,6),(90,6)]
[(70,0),(50,1),(30,2),(10,3),(80,3),(60,4),(40,5),(20,6),(90,6)]
Thanks.
Dons, thanks, now I'm not sure what I did that made the right output. Yes that code in my comment is a syntax error (and I can't fix it or comment there because I don't have the browser cookie any more, sigh). I don't see any way to fix this except with "zip", which is a bit disappointing, but oh well. (Oh, looks like I can put edits into a queue, unlike on mathoverflow).
Solrize's comment is correct, it seems. The first result is because the bar associates more loosely than the comma. This is documented in dons' link under the "Parallel List Comprehensions" section. Not sure what can be done about this...
The following is terribly ugly (duplicate bindings of (x,y)) but fixes solrize's syntax error by the way...
zs <- [(x,y) | (x,y) <- [(x,y) | x<-xs | y<-ys], then sortWith by y]
What would be ideal would be some way to parenthesize |
sections of parallel list comprehensions, such as the following:
zs = [(x,y) | (x<-xs | y<-ys), then sortWith by y]
Looks like a bug to me. It is at minimum a failure to communicate clearly what the syntactic translation is. solrize's provdied link states:
Given a parallel comprehension of the form:
[ e | p1 <- e11, p2 <- e12, ...
| q1 <- e21, q2 <- e22, ...
...
]
This will be translated to:
[ e | ((p1,p2), (q1,q2), ...) <- zipN [(p1,p2) | p1 <- e11, p2 <- e12, ...]
[(q1,q2) | q1 <- e21, q2 <- e22, ...]
...
Intuition would put the , then sortWith by y
in the final ellipsis:
[ (x,y) | x <- xs
| y <- ys
, then sortWith by y ]
Which would translate to
-- this produces the same result as your zs'
[ (x,y) | (x,y) <- zip [x' | x' <- xs]
[y' | y' <- ys]
, then sortWith by y ]
However, it actually seems to go in the second-to-last ellipsis spot:
[ (x,y) | x <- xs
| y <- ys, then sortWith by y
]
Translating to
-- this produces the same result as your zs
[ (x,y) | (x,y) <- zip [x' | x' <- xs]
[y' | y' <- ys, then sortWith by y']
]
精彩评论