Hi all, this is my first blogpost ever, so be gentle.

Today I was struck with a crash in Haskell. It just jumped into gdb. I really didn’t expect the code to crash. Also since it all happened in an iphone simulator I didn’t get much output. Then my coleague pointed out that he is seeing a <<loop>> in his xcode console (I didn’t see it). Knowing this, I reviewed my changes and found the error. It was an additional apostrophe in a list of sequential assignments in a let block. The code was similar to this:

result = let a' = f0 b' = f1 a'' a'' = f2 b' a' in a''

The a” on the second line is obviously having one apostrophe too much. I thought about what can be done about this. This is Haskell alright! I should have been warned in the compile time. What can I do to make it never happen again? Monads give me a sequence, but I actually don’t need any monad. Then I realized I can just use the Identity monad. After rewriting:

result = runIdentity $ do a' <- return f0 b' <- return $ f1 a'' a'' <- return $ f2 b' a' return a''

This fails because the a” is not in scope. Great! I always thought about the Identity monad as a trivial example, not useful for anything. And voila … this is a real life situation where it actually helps. Also by using the monad I make the originally implicit sequence of assignments explicit for the reader of my code. Now, what can I do about the ugly returns? There must be a solution for this. After some talks on #haskell I see several choices. I can use a nested let:

result = let a' = f0 in let b' = f1 a'' in let a'' = f2 b' a' in a''

Semantically identical to the original, but too ugly! Let’s see how anouther solution looks:

result = runIdentity $ do let a' = f0 let b' = f1 a'' let a'' = f2 b' a' return a''

I was pointed out, that all let blocks in a monad are sequenced, so I just put let on each line. This looks pretty good. In doesn’t look that good in my real code, which is about ten lines of sequence and also some pattern matching on the left side, but this is where I goit so far. Anyway, I think this is a nice way to prevent unintended loops as well as to improve readability.

What do you think? Is using of the Identity monad semantically/performance equivalent to the original code? Is there any way to make it even nicer (without any drastic pre-processing rewrite rules)?