Extending the work in my last post, I've developed a way to express an almost type-safe, general monad in C#. Similar to my module translation, the single monad object becomes a pair of co-operating objects, only one of which the monad implementor must define. Since C# cannot abstract over type constructors, I had to exploit the only feature that could accomodate the flexibility I needed: C#'s dynamic typing.

// The Monad object, indexed by a singleton type that implements the

// monad operations.

public sealed class Monad<M, T>

where M : struct, IMonadOps<M> { ... }

// An object that implements operations on the monad's encapsulated

// state.

public interface IMonadOps<M>

where M : struct, IMonadOps<M>

{

/// Return the encapsulated state for the monad's zero value.

object Zero<T>();

// Return the encapsulated state for the 'unit' operation.

object Unit<T>(T t);

// Perform a bind operation given the monad's e…

// The Monad object, indexed by a singleton type that implements the

// monad operations.

public sealed class Monad<M, T>

where M : struct, IMonadOps<M> { ... }

// An object that implements operations on the monad's encapsulated

// state.

public interface IMonadOps<M>

where M : struct, IMonadOps<M>

{

/// Return the encapsulated state for the monad's zero value.

object Zero<T>();

// Return the encapsulated state for the 'unit' operation.

object Unit<T>(T t);

// Perform a bind operation given the monad's e…