Hi,

I'm writing my first real Haskell program and I came up with the following code snippet.

---
let x' = x \+ dist \* dir
    nx' =  normal geometry
    wi = (-1) \* dir
    in do
        (p, wo) <- brdfCosSampling reflector nx' wi    
        let color' = p \** color
            q = min 1 (scalarContribution p)
            in do
                sampler <- biasedCoinSampler q
                        (radianceSampler surfaces x' wo (q \* color'))
                        (terminalRadianceSampler surfaces x' nx' ((1-q) \* color'))
                sampler
---

This works just fine but I don't like the way I had to indent the code because of alternating lets and dos.
I would like to indent the code more like an imperative code i.e. like this

---
let {
    x' = x \+ dist \* dir ;
    nx' =  normal geometry ;
    wi = (-1) \* dir ;
} in do {
    (p, wo) <- brdfCosSampling reflector nx' wi ;
let {
    color' = p \** color ;
    q = min 1 (scalarContribution p) ;
} in do {
    sampler <- biasedCoinSampler q
            (radianceSampler surfaces x' wo (q \* color'))
            (terminalRadianceSampler surfaces x' nx' ((1-q) \* color')) ;
    sampler ;
}}
---

but without braces and semicolons. Following works also, but is ugly (and probably less efficient?).

---
do
    x' <- return $ x \+ dist \* dir
    nx' <- return $  normal geometry
    wi <- return $ (-1) \* dir
    (p, wo) <- brdfCosSampling reflector nx' wi
    color' <- return $ p \** color
    q <- return $ min 1 (scalarContribution p)
    sampler <- biasedCoinSampler q
            (radianceSampler surfaces x' wo (q \* color'))
            (terminalRadianceSampler surfaces x' nx' ((1-q) \* color'))
    sampler
---

Is there some nice trick to do this?