On Thu, 5 Oct 2006, Ch. A. Herrmann wrote:
Henning Thielemann wrote:
...
The notation [f x | x <- xs] describes operations on list elements, and looks like the imperative "forall x in xs do f x", whereas map f xs is a list transformation. The second one is more abstract, isn't it?
for that simple example yes, but what's about list comprehensions like:
sequence of parsers: (p <+> q) r = [ ((x,y), r2) | (x, r1) <- p r, (y, r2) <- q r1 ]
More abstract: p <+> q = runStateT (liftM2 (,) (StateT p) (StateT q)) If you give the parsers the StateT type, then it is even <+> = liftM2 (,)
or triples: [ (x,y,z) | x<-[1..n], let x2=x*x, y<-[1..x], let y2=y*y, let z=isq (x2,y2), x2+y2==z*z ]
This is rather a 1:1 translation of an imperative program, a bit shorter, ok, but it will certainly not impress an imperative programmer. I find it more important that the generation of pairs, where the first element is smaller than the second one, can be nicely separated from the Pythagoras check, due to laziness.