Parse

I had one of those moments last week.

One of those “how did I never see this before” moments.

Although I have a suspicion based on a talk I gave a couple of years ago at NSSpain that it was more of a “I understood this at one time, how did I forget it” moments.

Anyway, I’d reread a part of Paul Chiusano and Runar Bjarnason’s book Functional Programming in Scala. I like and recommend this book even for those of us who don’t code in Scala.

I was implementing an example of a Parser in Swift. Something like this:

struct Parser<A> {
  let parse: (Substring) -> (A, Substring)
}

They have an example of a Random Number Generator in an earlier chapter. You create an RNG that returns a random Int. Then you use map() to transform it into an RNG that returns Doubles or Bools. Then you learn to use flatMap() to return the next five random somethings or the first random something that meets a condition. This is a common example for State patterns.

Later they are looking at Parser combinators and I translated it to Swift as something like the above.

Then I stopped.

This looks a lot like State.

struct State<S, A> {
    let run: (S) -> (A, S)
}

In fact for Random Number Generators we defined a type named RNG and created our Random number generator that returned As as being a typealias Random&lt;A&gt; = State&lt;RNG, A&gt;.

So Parser could be seen as essentially typealias Parser&lt;A&gt; = State&lt;Substring, A&gt; where we replace run with parse.

All of a sudden Parser Combinators felt more like something that belonged to a family and not some new concept.

So that’s why we struggle with these abstractions - at some point we look at a new concept and say, “wait, that looks just like this other thing.”

This month’s comic is not very visual. Just the “mind-blown” emoji because I couldn’t find the “repeatedly smacking myself in the head for not seeing it sooner” emoji.

Parser

I love that our understanding of these notions deepens over time.