background preloader

You Could Have Invented Monads! (And

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. Many of the problems that monads try to solve are related to the issue of side effects. Side Effects: Debugging Pure Functions In an imperative programming language such as C++, functions behave nothing like the functions of mathematics. Solution and Related:  Monads

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.

How would I even use a monad (in C#)? | Twisted Oak Studios Blog How would I even use a monad (in C#)? As you may have guessed, based on everyone ever trying to explain what they are, monads are an interesting concept. I assume the difficulty in explaining them stems from the high level of abstraction, compared to related ideas like “being enumerable”, but I won’t be trying to explain what a monad is in this post. Instead I’m going to show you how, in C#, you can take advantage of a type being a monad. If you do want an explanation of what a monad is, I recommend the marvels of monads, an old post that made the concept “click” for me. Querying your Monad Language integrated query (LINQ) was a major feature introduced way back in C#3. // before linqvar transformedList = new List();foreach (var item in inputList) { transformedList.Add(item * 2 + 1);}// after linqvar transformedSequence = from item in inputList select item * 2 + 1; For example, suppose we want to be able to query and transform tasks (a.k.a. public static void PrintQueryNullables() { int?

IO: You may say I'm a monad, but I'm not the only one! One of the things I love about Haskell is its tools for abstracting computation. There are so many different ways to look at a given problem, and new ones are being invented/discovered all the time. Monads are just one abstraction, a popular and important one. When you’re learning Haskell, you’re told ’IO is a monad’, and whether or not you understand what that means, you start to see the significance of binding impure values, returning pure ones, using do notation, and so on. Speaking of Applicative and Functor, I’ll also be introducing some of those other computation abstractions, and showing you the same code using several different styles. A quick review: functors A concept I’ll be referring to a lot in this post is the idea of computing on things in boxes. Think of a Maybe Int as a box that might contain an Int and might not. fmap turns a regular function into a function that looks inside the box first, and doesn’t try to apply itself if the box is empty. succ (Just 5) Easy, right?

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 Lambda Calculus First published Wed Dec 12, 2012; substantive revision Fri Feb 8, 2013 The λ-calculus is, at heart, a simple notation for functions and application. The main ideas are applying a function to an argument and forming functions by abstraction. The syntax of basic λ-calculus is quite sparse, making it an elegant, focused notation for representing functions. Functions and arguments are on a par with one another. 1. The λ-calculus is an elegant notation for working with applications of functions to arguments. λx[x2 − 2·x + 5]. The λ operators allows us to abstract over x. The first step of this calculation, plugging in ‘2’ for occurrences of x in the expression ‘x2 − 2·x + 5’, is the passage from an abstraction term to another term by the operation of substitution. This example suggests the central principle of the λ-calculus, called β-reduction: (β) (λx[M])N ⊳ M[x := N] 1.1 Multi-argument operations What about functions of multiple arguments? hypotenuse-length := λa[λb[√(a² + b²)]] 2. 3.

Abstraction, intuition, and the “monad tutorial fallacy” | blog :: Brent -> [String] While working on an article for the Monad.Reader, I’ve had the opportunity to think about how people learn and gain intuition for abstraction, and the implications for pedagogy. The heart of the matter is that people begin with the concrete, and move to the abstract. Humans are very good at pattern recognition, so this is a natural progression. By examining concrete objects in detail, one begins to notice similarities and patterns, until one comes to understand on a more abstract, intuitive level. Unfortunately, there is a whole cottage industry of monad tutorials that get this wrong. But now Joe goes and writes a monad tutorial called “Monads are Burritos,” under the well-intentioned but mistaken assumption that if other people read his magical insight, learning about monads will be a snap for them. What I term the “monad tutorial fallacy,” then, consists in failing to recognize the critical role that struggling through fundamental details plays in the building of intuition.

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. (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. This being lisp, we could introduce a special syntax to take away the boilerplate: and we have let back! (with-binder bind [a 1 b (inc a)] (* a b))

Writing a Raytracer in Common Lisp - Part 1 concrete monads 1 : Maybe, Either, list, IO 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)

Reusing Thunks for Recursive Data Structures in Lazy Functional Programs - Yasunao TAKANO Monads, lifting, join, and side-effecting actions. While playing around with querying ElasticSearch I bumped into something that I hadn’t really understood explicitly before about monads, nesting, and IO. Rather than blather on, I’m going to share a “literate” ghci session that demonstrates the point. Main editing change I made was to remove duplication in the output from querying the type :t in ghci. import Network.HTTPimport Control.Monad (join, liftM) let url = " Importing the HTTP client library, a simple one based on IO. simpleHTTP (getRequest url) >>= liftM putStrLn . getResponseBody But that doesn’t print anything. λ> :t simpleHTTP (getRequest url) :: IO (Network.Stream.Result (Network.HTTP.Response String)) λ> :t simpleHTTP (getRequest url) >>= getResponseBody :: IO String So we’ve got an IO action returning a String. For our purposes, fmap and liftM mean the same thing. On a hunch, I broke out putStrLn into a separate bind (>>=) call, allowing me to eliminate the lifting (liftM).

Related: