Haskell98はdo経由せずにそのまま変換するようになってるな
[ e | p <- l, Q ] =
  let ok p = [ e | Q ]
      ok _ = []
  in concatMap ok l
[ n | (n,True) <- zip [1,2,3,4,5] [True,False,True,False,False] ]
  => let ok (n,True) = [n]; ok _ = [] in concatMap ok (zip [1,2,3,4,5] [True,False,True,False,False])
意味はほぼ一緒だが