Previously we looked at using IO without side-effects in C# by deferring the execution of side-effects. Rather than immediately performing IO, we wrapped up side-effecting operations in an
IO type and used combinators like
SelectMany to work within that type, so we could use
IO values without having to give up the benefits of pure functions by executing the side-effect.
This is a useful technique, but it has the drawback that the
IO instances assembled with these combinators are opaque – there is no way for us to inspect them and work out what the represent. We know an
IO<String> is some IO operation that will result in a string, but is it
In this post we’ll look at another way of representing side-effecting (and other) operations that addresses this drawback.