20200315132716.md

Monads

Monads are Functors[[20200315171208]].

Monads define a constructor function which turns a value into that Monad—which I refer to as the Application function. In Haskell, this function is return, but it (understandably) takes different forms in other languages. In fantasy-land (monad library for Javascript) the Application function takes the form Type.of(x).

Monads define a chain function. If I want a monad which represents a persons name, and I want to compute the persons last name by splitting based on spaces, both the full name or the last name could wind up missing. The persons Full Name could be nil at runtime, or there could be a string but no spaces, giving my a name but no clear last name. If this happens I can use a Maybe monad with chain.

const lastName = name.chain(str => {
    const parts = str.split(' ')
    if (parts >= 2) {
        return Maybe.Just(last(parts))
    } else {
        return Maybe.Nothing()
    }
})

The Monad Laws 1. Calling chain on a monad of a single value must return a monad equivalent to the result of the provided function. If f is a function which returns a monad of type Box, then Box.of(x).chain(x => f(x)) must be equivalent to f(x). This is referred to as left identity, as in, if the Application (identity) function is on the left, calling chain is irrelevant. 2. When passed its own Application function, chain must return a monad equivalent to itself. box.chain(Box.of) must be equivalent to box. This is referred to as right identity, as in, if the Application (identity) function is on the right, calling chain is irrelevant. 3. The order of execution of chain is irrelevant; only the left-to-right order of chain matters. Therefor

const lastNameLength = name
    .chain(getLastName)
    .chain(getLength)

must be equivalent to

const lastNameLength = name
    .chain(str => getLastName(str).chain(getLength))

Rule 3 is almost a byproduct of 1. If chain must return a monad equivalent to the result of the passed function, then calling chain in or outside that function shouldn't effect the outcome.

Monads are referentially transparent[[20200315130636]].

#software #monadic