Tuesday, March 8, 2011

Silly little details

Sometimes you have these moments when some silly little detail you've missed for so long suddenly becomes clear and it changes your entire outlook. I just had one of those moments. My friend Harry came to ask me about the State monad. Now, I'm no monadic cowboy, but I've slowly grokked how to use them a little bit.

So, we were discussing the structure of return and bind for State, and started to talk about runState. In my attempts to explain it, I realized something silly -- it's an accessor function for the record type State!! Duh! Now it call becomes clear!

All along I had assumed that runState was some function floating around in some file somewhere that I just hadn't found yet. But no, it's just the field accessor for the runState field in the State record. No one ever constructs a State instance using that syntax, but they access it that way all the time. It turns out:


let m = State (\s -> let foo = ... in (foo a, s))


is synonymous with


let m = State { runState = (\s -> let ...)}


so when I do


let (a,s') = runState m s


I'm really just getting that function back out of the State record and applying it to s!!

Woah.

I'm not really sure how I've missed this the whole time. Probably others who read this will wonder how I got this far without figuring it out. But, there it is.

Maybe this will help someone. It's sure helped me.