Hi myloran,
Thank for your the kind words. Functional programming is almost like a meta-language for writing functional programming. You often write an abstract representation of what you want to code, and there's a "reify" stage that actually "writes" the resulting code. The GUI library in the book would be an example of that.
If you want to get really esoteric, it can also be interesting to investigate whether Stream and Cell are themselves monads. I think neither of them is, but cell is tantalizingly close to being one. Unfortunately C# doesn't have functional ideas built into the language and libraries like a real functional language does.
Most of my own FRP programming is fairly basic, but there's no limit to the useful ways to apply FP techniques to FRP programming. You tend to find that when learning FP: You learn all the advanced mind-blowing type classes and type level programming and so on, but with experience you realize that 98% of the time, plain functions are the best way to do FP.
The use of inheritance was a carefully thought out decision to structure the API in a way that was as idiomatic to the target language as possible. The functional way to implement StreamSink for example, would be this kind of thing:
(s, sSink) <- newStreamSink
This works great in Haskell but tends to be quite clunky in mainstream languages.
It's true that inheritance is harmful, but this API makes such limited use of it that pros outweigh the cons, because inheritance fits the API so nicely. Usability by people unfamiliar with FP was also a major design goal.