Can I avoid "rightward drift" in Haskell?

Viewed 1409

When I use an imperative language I often write code like

foo (x) {
    if (x < 0) return True;
    y = getForX(x);
    if (y < 0) return True;

    return x < y;
}

That is, I check conditions off one by one, breaking out of the block as soon as possible.

I like this because it keeps the code "flat" and obeys the principle of "end weight". I consider it to be more readable.

But in Haskell I would have written that as

foo x = do
    if x < 0
        then return x
        else do
            y <- getForX x

            if y < 0
                then return True
                else return $ x < y

Which I don't like as much. I could use a monad that allows breaking out, but since I'm already using a monad I'd have to lift everything, which adds words I'd like to avoid if I can.

I suppose there's not really a perfect solution to this but does anyone have any advice?

4 Answers
Related