background preloader

Monads

Facebook Twitter

Functors

Tonymorris. Maybe. Why Use Monads. A Reader monad for the Visitor pattern. Programming with impossible functions, or how to get along witho. A recent paper by Hyland and Power speculates about an alternative universe in which languages like Haskell develop along a path in which monads don't play a starring role. This post will be about making tentative steps in that direction to see what developer-friendly alternatives might exist to solve problems like writing code using I/O in an elegant and readable manner. I think all of what I'll say was worked out 20 years or more ago but there may be some good reasons to think about this stuff again.

We'll need some Haskell language extensions > {-# LANGUAGE GADTs, RankNTypes, TypeOperators #-} > import Prelude hiding (read, IO)> import Control.Monad.Reader hiding (Reader) IntroductionLet's start with this problem: We'd like to write pure functional code to read input values of type i sequentially from some source. Here's a general sketch of how I plan to proceed: In some sense we want to add a new language feature to Haskell. > data Reader i x where > RValue :: x -> Reader i x That's it. You Could Have Invented Monads! (And. If you hadn't guessed, this is about monads as they appear in pure functional programming languages like Haskell. They are closely related to the monads of category theory, but are not exactly the same because Haskell doesn't enforce the identities satisfied by categorical monads. Writing introductions to monads seems to have developed into an industry. There's a gentle Introduction, a Haskell Programmer's introduction with the advice "Don't Panic", an introduction for the "Working Haskell Programmer" and countless others that introduce monads as everything from a type of functor to a type of space suit.

But all of these introduce monads as something esoteric in need of explanation. But what I want to argue is that they aren't esoteric at all. In fact, faced with various problems in functional programming you would have been led, inexorably, to certain solutions, all of which are examples of monads. Many of the problems that monads try to solve are related to the issue of side effects. The sequence monad. I'm currently reading the excellent tutorial on monads here: and paraphrasing it to help me understand. You may prefer to look at my earlier post first.

This is a follow-up to that. We've already seen that ((fn [a] ((fn [b] (* a b)) 2)) 1) is the same as: The functional for loop (for [a (range 5) b (range a)] (* a b)) has a similar structure. Now the variables are being attached to members of sequences, and the earlier names can be used in the calculation of the later values. If we didn't have for, what could we write to get the same effect? (map (fn [a] (map (fn [b] (* a b)) (range a))) (range 5)) doesn't quite work, because the results are nested.

(mapcat (fn [a] (map (fn [b] (* a b)) (range a))) (range 5)) or: (mapcat (fn [a] (mapcat (fn [b] (list (* a b))) (range a))) (range 5)) to reproduce the same result as for. instead. Recap: The Monad. I'm currently reading the excellent tutorial on monads here: and paraphrasing it to help me understand. The simplest monad is let, the identity monad. (let [a 1] (let [b 2] (let [c (* a b)] (let [d (* a a)] (let [e (+ (* b b) (/ c d))] (let [f (+ c d e)] (let [g (- c)] (* a b c d e f g)))))))) The let above represents a complex computation. During the computation, values are computed, names are bound to values, values are used as inputs to functions.

(let [a 1] (let [b (inc a)] (* a b))) is just ((fn [a] ((fn [b] (* a b) ) (inc a)) ) 1) And it's easy to transform one into the other. If we didn't have let, how could we do this sort of thing and remain sane? (defn bind [value function] (function value)) This, by reversing the order of function and argument, allows us to write: (bind 1 (fn [a] (bind (inc a) (fn [b] (* a b))))) Thus putting the names nearer to the values they take. and we have let back!

F#: Pipelined Monads. #light type Definition = unit type internal ModelResultCatch<'T> = | ModelResultOK of 'T | ModelResultException of System.Exception type ModelResult<'T> = | ModelValue of 'T | DelayedModelValue of (unit->ModelResult<'T>) | Collision of Definition*Definition | UndefinedScope of string list | InvalidContainment of Definition*Definition | InvalidOperation of string member s.IsDelayed () = match s with | DelayedModelValue(_) -> true | _ -> false member s.IsException () = | ModelValue(_) -> false | _ -> true member s.Get() = | ModelValue(m) -> m | _ -> failwith "invalid operation" member s.Complete() = let rec loop x = match x with | DelayedModelValue work -> loop (work()) | _ -> x loop s member s.CastException<'U> () = | ModelValue(_) -> failwith "invalid cast" | DelayedModelValue(_) -> failwith "invalid cast" | Collision(d1,d2) -> ModelResult<'U>.Collision(d1,d2) | UndefinedScope(s) -> ModelResult<'U>.UndefinedScope(s) | InvalidContainment(d1,d2) -> ModelResult<'U>.InvalidContainment(d1,d2) module ModelResult = catch (e)

If monads did not exist, we would be forced to invent them. Over the weekend, I started myself a little F# project, a little more complicated than the little orrery clock I wrote at the end of last year -- hence the little flurry of F# unit test related posts. The project in question is a simple FxCop rule to identify methods with inadequate test coverage, so, if I were writing this in a conventional imperative language, the 1.override protected ProblemCollection Check(Member member) method would look roughly like (using the return ASAP refactoring of the arrow-antipattern) 1.if(IsInCategory1(member,...)) return Problems; 2.if(IsInCategory2(member,...)) return Problems; 3.if(IsInCategory3(member,...)) return Problems; 4.if(IsInCategory4(member,...)) return Problems; 6.return Problems; where each check either identifies the method as a definite pass or fail (the latter mutating the object state that the overall method also returns), or cannot tell.

Mindfuck: The Reverse State Monad. Wrapping IO, part 1. Wrapping IO, part 2. The previous post was a fairly silly example, unless of course it’s more useful than I realise However, here’s something that I can see a bit more use of, a monad that restricts reading and writing of files to two files, one to read from and one to write to. Again, the first step is to create a data type: This defines a type wrapping a function that takes a pair of handles (one for input and one for output) and returns an “IO action”. Turning this into a monad is straight forward (actually it’s similar to the Reader monad): To return a value we can simply drop the pair of handles and return the value in IO. In order to avoid having to manually open files and wire everything up I wrote the following convenience function: Yes, it does lack a bit in exception handling, but it’s good enough for now.

Then I can define the actions/functions that are available inside TwoFileIO. As a little test function I used this one, which reads two lines and then writes them in the reversed order: Null Considered Harmful. I hate null. More specifically I hate NullPointerExceptions(NPEs). Scala has an alternative, but let me explain why I hate NPEs. They're like evil, sneaky muppets. Remember the Martians on Sesame Street? They'd ask each other if a phone was a cow and then say "nope, nope, nope, nope. " To my eye, NPE looks a lot like "NoPE. " Me: Is my unit test working? Does all this code/test/fix/Martians/yelling have to be part of the game? The answer in Java and C# is "No! Some Craptacular Code First, what's the big deal?

Public interface Spaceship { public Martian getMartian(); } Spaceship spaceship = getSpaceshipSomehow(); Martian m = spaceship.getMartian() if (m ! Public interface Spaceship { public Martian getMartian(); } // the main method... The idea here is that some spaceships have Martians while others don't. Okay, let's try creating a holder that I'll call "Option" for reasons we'll see later. Unfortunately, this code has three holes and one major (huge) annoyance. Making it Optional in Scala. “For” hack with Option monad in Java. August 6, 2008 by Stephan Schmidt There has been some discussion going on in the blogosphere about monads, and especially about the Haskell Maybe monad or the Scala option class.

Those are ways to prevent problems with NULL and NPEs that Java lacks. Java returns NULL form many methods to indicate failure or no result. Suppose we have a method which returns a name: String name = getName("hello"); int length = name.length(); Some posts like the one from James show how to use options in Java. All have the problem that you need to unwrap the value inside the option / maybe. But there is a construct with syntactic sugar in Java which unwraps the value from inside another class: the for loop from Java 1.5. Option[String] option = getName("hello"); for (String name: option) { // do something with name } To make this work we need our option class to implement Iterable. public abstract class Option[T] implements Iterable[T] { } And the None and Some sub classes to return an empty iterator. A monad in C# for simplifying WPF multi-threading for a more res. jQuery is a Monad.

jQuery is a Monad January 18, 2009 at 4:53 am It’s said that every Haskell programmer writes their own monad tutorial, and with good reason: once you finally understand the definition and capabilities of a monad, you’ll be eager to try and break the mystique surrounding the concept of monads as a whole. To the outsider, monads are an impenetrable barrier to truly understanding Haskell; they’re cursed with a very unfortunate name, have bizarre syntax, and seem to do a thousand things at once.

However, monads aren’t hard to understand when you see them in action. As such, I present to you what may be the most widely-used monadic library in any language: the jQuery library, designed to bring Javascript back to its roots in functional programming and make AJAX and animations easy. The jQuery object, accessible through the jQuery variable or the $ shortcut, allows you to query or make DOM elements using CSS selectors or XPath queries, as shown below: $("span").fadeIn("slow").text("Alert!

") Bam. A monad tutorial for Clojure programmers (part 4) « On Clojure. In this fourth and last part of my monad tutorial, I will write about monad transformers. I will deal with only one of them, but it’s a start. I will also cover the probability monad, and how it can be extended using a monad transformer. Basically, a monad transformer is a function that takes a monad argument and returns another monad. The returned monad is a variant of the one passed in to which some functionality has been added. Consider two monads that I have discussed before: the maybe monad and the sequence monad. So how can we create a monad that puts the maybe monad functionality inside sequence monad values? First, as a reminder, the definitions of the maybe and the sequence monads: (defmonad maybe-m [m-zero nil m-result (fn [v] v) m-bind (fn [mv f] (if (nil?

And now the definition of the maybe monad transformer: (defn maybe-t [m] (monad [m-result (with-monad m m-result) m-bind (with-monad m (fn [mv f] (m-bind mv (fn [x] (if (nil? (def maybe-in-sequence-m (maybe-t sequence-m)) How you should(n’t) use Monad. I’m often surprised by the fact that many people see monads as the be all and end all of Haskell’s abstraction techniques. Beginners often struggle over them thinking that they’re something incredibly important and complex.

In reality though, monads are neither important, nor complex, and that’s what I aim to show with this little tutorial about what other abstraction techniques you can use, and when they’re appropriate. First things first – IO The reason a lot of people come across monads is that they want to get on with interacting with the outside world – they want to do I/O. I’m going to get this out of the way quickly.

In Haskell, IO is kept in a carefully constrained box, because unconstrained it violates referential transparency (that is, you can get multiple answers from the same call to the same function depending on what the user happens to type/how they wibble the mouse/etc). Here’s a few examples: These can be stuck together with the handy do notation: Putting things in boxes. A monad tutorial for Clojure programmers (part 1) Monads in functional programming are most often associated with the Haskell language, where they play a central role in I/O and have found numerous other uses.

Most introductions to monads are currently written for Haskell programmers. However, monads can be used with any functional language, even languages quite different from Haskell. Here I want to explain monads in the context of Clojure, a modern Lisp dialect with strong support for functional programming. A monad implementation for Clojure is available in the library clojure.algo.monads. Before trying out the examples given in this tutorial, type (use 'clojure.algo.monads) into your Clojure REPL.

You also have to install the monad library, of course, which you can do by hand, or using build tools such as leiningen. Monads are about composing computational steps into a bigger multi-step computation. Consider the following piece of code: (let [a 1 b (inc a)] (* a b)) This can be seen as a three-step calculation: Like this: A problem with monads? It took me a while, but I've finally gotten to the point I wanted to make. Take a look at the state monad: (define (bind M f) (lambda (ma) (let* ((intermediate (M ma)) (i-state (get-state intermediate)) (i-value (get-value intermediate)) (next (f i-value))) (next i-state)))) .

We would use this monad to chain together a bunch of procedures that will pass a `state variable' around. The procedures aren't actually `chained' though, they are `nested'. In order to extend the chain, we put a wrapper around the existing chain, catch its return value and feed the appropriate elements through to the next function in the chain. The structure is like a set of Russian dolls where the initial function is the smallest and the subsequent functions wrap around it. When we run this monad, the first thing we have to do is invoke the next inner monad. The state monad is not tail recursive. I suppose this is a trivial point for some people, but I find this to be remarkable. More monads. As Pascal Costanza pointed out in a comment from yesterday, monadic style isn't just used for sequencing and stringing together I/O.

The key notion is that if your language can't do X directly (for whatever X is), you can do it indirectly by piecing together little program fragments into a program that does X and then running that. Monadic style has the added advantage that you can separate the program fragments from the `plumbing' to keep the abstraction nice and clean. So what's this `unit' and `bind' stuff that monad tutorials go on about? These are the two primitive elements that you need to bootstrap yourself into monad land. Bind is hard to understand because it has a strange type signature.

Let's take a look at a bind programs. The `state' monad allows you to pretend that there is a location that holds some mutable state. . This is a bit messy and confusing, so I'll try to restate it again in a simpler manner. How about them Monads? Much Ado About Monads – List Edition. Why monads have not taken the Common Lisp world by storm. jQuery is a Monad. A tour of the Haskell monad functions. The Mother of all Monads. Wadler: Monads. From Monoids to Monads. Operads and their Monads. Monads for the Working Haskell Programmer. State Monad in simple terms. Lazy Error Handling in Java, Part 1: The Thrower Functor.

Higher-Order Java Parallelism, Part 1: Parallel Strategies and t. A complex monad in metaC++ Monads in C++ template metaprogramming. The Essence of Functional Programming. Monads in Ruby, Part 1: Introduction. The Maybe Monad in Ruby. The Comonad.Reader » Monads for Free. Monads - Another way to abstract computations in Scala.