
Simon Peyton Jones answered me:
| > do { a <- getChar | > ; rec { b <- f c | > ; c <- g b } | > ; putChar c | > ; return b }
| This last point notwithstanding, | I find the scoping rules very unintuitive! | (b and c appear to escape their apparently nested scope.)
well you are happy with ^^^^^
(Let's say: I got used to it...)
do { z <- getChar ; let { b = f c ; c = g b } ; putChar c ; return b }
It's just the same!
Indeed; I had not noticed that. (I am spoilt by layout, and had never ``seen'' those braces before.) However, if you write those braces, there is no reason anymore to omit the ``in do'' at the end! This variant of let is only motivated by layout... Analogously, is | > do { a <- getChar | > ; rec { b <- f c | > ; c <- g b } | > ; putChar c | > ; return b } equivalent to | > do { a <- getChar | > ; rec { b <- f c | > ; c <- g b } in do | > { putChar c | > ; return b } ? Is | > do { rec { b <- f c | > ; c <- g b } | > ; putChar c | > ; return b } equivalent to | > rec { b <- f c | > ; c <- g b } in do | > { putChar c | > ; return b } ? Would ``dorec'', in analogy with ``letrec'', perhaps be a better name? Wolfram