Can monads help me my refactor code for an enhanced data structure?

Monads are definitely not about packing and unpacking data structures. Monads are about representing computations as values. A computation is a procedure, (command, a set of instructions) bound with an execution environment and producing values and affecting the environment. Monad, in this case, is a design pattern, along with an abstraction, that helps to deal with this.

Concerning your problem, monads may be of help or maybe not. What you want is to make your code generic with respect to the data representation. What you need is a proper abstraction. In your case, you don’t have one. A type in OCaml defines a data representation, not an abstraction. Your functions depend on a particular representation. By exposing the representation you break the abstraction. The abstractions are defined by module types (signatures) and are implemented by modules. So what you need is a module Dist that will abstract the representation of a dist. Now your code will depend on a Dist.t abstraction, and will not break when you will change its representation.

Now, when a monad can help:

  1. you need to pass a state to many functions. You can either pass it explicitly as a parameter to all functions, i.e., many of your functions will have type 'a -> state -> state, you can use a mutable global variable, you can use OO. Or you can use a state monad. In fact, underneath the hood, a state monad is a function that takes an 'a value and returns the state -> state function. So, since you have lots of functions that end with the state -> state type, the State monad just captures this idea into an abstraction of state transformation. (There are also two refinements, Reader and Writer, that do the transformation in only one direction).

  2. You need to deal with computations that may diverge. You may use exceptions, but they hide the effect of the diverge from the type system. Thus you can use any partial computation monad (the Result Monad, the Option (Maybe) monad, etc) to work with the diverging computations explicitly.

  3. You would like to work with non-deterministic computations, i.e., functions that return several results. And you would like to express your algorithms in terms of deterministic functions. Then you can use the List monad.

  4. You need co-routines, generators, gotos, and arbitrary control flow, or you just want to confuse people that read your code, or you just want to show off. Use the continuation monad :slight_smile: Well, in fact, it has its own applications, for example in BAP we are using the continuation monad to implement non-deterministic Turing Machines so that we can jump between different computation in arbitrary order. It allows us to express algorithms in terms of deterministic machine, while the monad takes care of extending it to the non-deterministic case.

15 Likes