1

I'm struggling to try to understand monads in functional programming and how it applies on the language I work (Swift, a multi-paradigm language).

As far as I could understand Monad is a pattern to deal mainly with two programming problems: chaining operations while isolating state complexity from it (IO, log, error, uncertainty). Is it correct?

Thinking of that, it seems that Monads could be used to handle transactional/atomic operations in a functional solution. And it seemed to me (on this point) some similarities with Aspect-Oriented Programming: separate the managing of cross-cuting concerns and its complexity from the regular business logic.

Does it make sense?

Thanks!

PS: The question is not as as broad as "What is a Monad?".

Sergio
  • 583
  • 1
  • 5
  • 6
  • 2
    Possible duplicate of [What is a monad?](https://stackoverflow.com/questions/44965/what-is-a-monad) – AJF Jun 26 '18 at 12:40

3 Answers3

3

Monads are a unification of several things in computing that were previously treated as being separate. When I say "unification" I mean it in the same sense that a physicist would: just as Newtonian gravity unified planetary orbits with terrestrial ballistics, and Maxwell's equations unified electrical and magnetic fields, so monads unify the following:

  • Seqencing (do A, then B, then C).
  • Exception handling (Do A. If it fails then do B).
  • Parallel processing (do A and B in parallel, then combine their results).
  • Non-determinism (Do A. For each possible result, do B. For each possible result, do C).
  • State machines.
  • Logic programming, a la Prolog.

And probably some more that I've forgotten about. Once you understand the general theory of monads you realise that it applies to lots of things, just like Maxewll's equations opened up the whole electromagnetic spectrum instead of us thinking that light and radio were two separate phenomena and hence not realising there was some really interesting stuff in between them.

One side effect of this generality is that you can write your own control-flow constructs. Haskell versions of "while" and "for" are not built in, they are part of the standard library. If you want something different then you can write it.

The core concepts in monads are "bind" (i.e. the (>>=) operator) and "return" (which is a really dumb name, but we are stuck with it). There are some basic laws which these have to obey. Roughly speaking, the two operations aren't allowed to do anything underhand. So "return" isn't allowed to have any side effects, and rearranging the brackets in a daisy chain of "bind" operations isn't allowed to change the meaning of the program.

This is really abstract stuff, which is why it looks weird to programmers raised on conventional imperative languages. Only when you have understood half a dozen different monads do you appreciate the fundamental unity of the concept. People learning Haskell first encounter the IO monad because you need it for "Hello World". At that point it just looks like a strange way of doing what every other programming does. This is because the IO monad is a model of the way that every other programming language (except Prolog) works; a sequence of actions that have effects on the real world, including named locations in physical memory.

The big advantage of Haskell monads is that, unlike every other programming language, it is not trapped in the IO monad. You can sort-of define monads in other languages, but they still get executed in what Haskell would see as the IO monad. Because Haskell is pure it lets you escape the constraints of IO and define new monads as true abstractions.

Paul Johnson
  • 17,438
  • 3
  • 42
  • 59
1

It is difficult to come up with a succinct description of monads. I have a slightly different take on the question than @PaulJohnson does.

In a sense, yes, you are right about monads. They do allow for chaining operations and managing complexity. But other mechanisms exist to do that as well. Monads go further.

Monads provide a "context" in which calculations can be performed. They provide a structure and follow some specific rules. These rules are common but the way individual monads follow them is specific to that monad.

For example:

  • the Option monad defines the context in which the data to be operated on may or may not exist. It obeys the monadic rules based on how they apply to this particular context.

  • The List monad defines a context in which their may be zero or more elements of data to be operated on. An alternative view of the List monad is that it provides zero or more possible values to operate on. This is why it is usually easy to create a "cross product" of multiple lists in most functional languages.

  • The Future monad (called different things in different languages) defines a context in which the data to be operated on may not be available yet.

There are many other monads, each defining its own context for operations to occur.

The rules that monads follow are what allow us to use them as abstractions that hide the complexities of the contexts so effectively while chaining simple operations together inside those contexts.

This is really a large topic. It has been suggested that there is no single (simple) answer that will give someone the 'aha' moment they need to really understand monads. You have to go through the struggle yourself to finally 'get' it. Don't worry about it. You can use monads using 'cookbook' recipes while you work to better understand them. At some point it will click and you will see what the fuss is all about.

The you will find yourself unable to explain them to anyone else. :)

BTW, there are a couple of really good resources that I have gone back to multiple times when dealing with monads. The first is a wonderful video called Don't Fear the Monad by Brian Beckman. The second is a series of blog posts: Monads are Elephants.

melston
  • 2,198
  • 22
  • 39
  • 1
    [Coming up with a succinct definition is easy](https://stackoverflow.com/questions/3870088/a-monad-is-just-a-monoid-in-the-category-of-endofunctors-whats-the-probleⅿ); *understanding* it may be a problem :) – chepner Jun 26 '18 at 19:11
0

At the risk of being overly simplistic; in the world of Monads you are expected to declare your Aspects via the type system. So aspects are tracked explicitly by the compiler, since you can write a Monad which handles Transactions or Logging concerns for you.

With monads you are able to statically (at compile time) declare your effects separately from your core logic, with aop you do this dynamically (at run time) with a much weaker ability to reason algebraically about aspects you have threaded into your codebase.