background preloader

You Could Have Invented Monads! (And Maybe You Already Have.)

You Could Have Invented Monads! (And Maybe You Already Have.)
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. 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. f,g :: Float -> Float f',g' :: Float -> (Float,String) which implies that Related:  Monads

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. I thought I was a pro at monads after discovering liftM, but I still hadn’t really made the jump to understanding monads in general, rather than as something specific to impure IO operations. 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. succ (Just 5) We can do this: Pow. Yup.

Haskell for all: Introductions to advanced Haskell topics Many people bemoan the sharp divide between experts and beginning Haskell programmers. One thing I've noticed is that "advanced" Haskell topics all have one thing in common: there exists only one good tutorial on that topic and only the experts have found it. This post is a collection of links to what I consider to be the definitive tutorials on these topics. Monads Monads are technically not an advanced Haskell topic, but I include this topic in the list because the vast majority of monad tutorials are terrible and/or misleading. Monad Transformers One thing that perpetually boggles me is that the blogosphere has almost no posts explaining how to use monad transformers. Parsing Outsiders comment that monads only exist to paper over Haskell's weaknesses until they discover monadic parsers. You also want to understand parser combinators for another reason: Haskell parser combinator libraries are light-years ahead of Haskell regular expression libraries. Free Monads Coroutines Lenses Conclusion

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. This is why it’s such good pedagogical practice to demonstrate examples of concepts you are trying to teach. It’s particularly important to note that this process doesn’t change even when one is presented with the abstraction up front! Unfortunately, there is a whole cottage industry of monad tutorials that get this wrong.

Learn Haskell Fast and Hard I really believe all developers should learn Haskell. I don’t think everyone needs to be super Haskell ninjas, but they should at least discover what Haskell has to offer. Learning Haskell opens your mind. Mainstream languages share the same foundations: variablesloopspointersdata structures, objects and classes (for most) Haskell is very different. But learning Haskell can be hard. This article will certainly be hard to follow. The conventional method to learning Haskell is to read two books. In contrast, this article is a very brief and dense overview of all major aspects of Haskell. The article contains five parts: Introduction: a short example to show Haskell can be friendly.Basic Haskell: Haskell syntax, and some essential notions.Hard Difficulty Part: Functional style; a progressive example, from imperative to functional styleTypes; types and a standard binary tree exampleInfinite Structure; manipulate an infinite binary tree! 01_basic/10_Introduction/00_hello_world.lhs Introduction ou

concrete monads 1 : Maybe, Either, list, IO Haskell for all 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. λ> simpleHTTP (getRequest url) >>= getResponseBody >>= putStrLn {"took":11,"timed_out":false ...

LTMT Part 3: The Monad Cookbook Introduction The previous two posts in my Less Traveled Monad Tutorial series have not had much in the way of directly practical content. In other words, if you only read those posts and nothing else about monads, you probably wouldn't be able to use monads in real code. This was intentional because I felt that the practical stuff (like do notation) had adequate treatment in other resources. In this post I'm still not going to talk about the details of do notation--you should definitely read about that elsewhere--but I am going to talk about some of the most common things I have seen beginners struggle with and give you cookbook-style patterns that you can use to solve these issues. Problem: Getting at the pure value inside the monad This is perhaps the most common problem for Haskell newcomers. main = do lineList <- lines $ readFile "myfile.txt" -- ... do something with lineList here That code generates the following error from GHC: Both of these functions are defined in Prelude.

How I learned to understand Monads : haskell Why Do Monads Matter? « Sententia cdsmithus (A Side Note: I’ve been formulating the final thoughts on this post for about a week now. In an entirely unrelated coincidence, a good friend of mine and fellow Haskell programmer, Doug Beardsley, ended up writing two posts about monads over the weekend as well. Weird! But don’t fret; this isn’t really the same thing at all. I’m not writing to teach Haskell programmers how to use monads. I’m writing about a kind of intuition about why these concepts turn out to matter in the first place. Category Theory for Software Development? Match made in heaven? If you’re a software developer, have you heard about monads and wondered what they were? Or if you’re interested in mathematics, have you heard murmurs in the past about how category theory interests computer science people? These are the kinds of questions I begin with. Ready? Computer Programming and Functions: A Tenuous Relationship Quick quiz: Do computer programmers use functions? The truth, though, is a bit more complicated. Oh no…

The Comonad.Reader » Mirrored Lenses Lenses are a great way to deal with functional references, but there are two common issues that arise from their use. There is a long-standing folklore position that lenses do not support polymorphic updates. This has actually caused a fair bit of embarrassment for the folks who'd like to incorporate lenses in any Haskell record system improvement.Access control. It'd be nice to have read-only or write-only properties -- "one-way" or "mirrored" lenses, as it were. Moreover, lenses are commonly viewed as an all or nothing proposition, in that it is hard to mix them with arbitrary user functions.Finally there is a bit of a cult around trying to generalize lenses by smashing a monad in the middle of them somewhere, it would be nice to be able to get into a list and work with each individual element in it without worrying about someone mucking up our lens laws, and perhaps avoid the whole generalized lens issue entirely. We'll take a whack at each of these concerns in turn today. Getters

A Fistful of Monads - Learn You a Haskell for Great Good! When we first talked about functors, we saw that they were a useful concept for values that can be mapped over. Then, we took that concept one step further by introducing applicative functors, which allow us to view values of certain data types as values with contexts and use normal functions on those values while preserving the meaning of those contexts. In this chapter, we'll learn about monads, which are just beefed up applicative functors, much like applicative functors are only beefed up functors. When we started off with functors, we saw that it's possible to map functions over various data types. We saw that for this purpose, the Functor type class was introduced and it had us asking the question: when we have a function of type a -> b and some data type f a, how do we map that function over the data type to end up with f b? We saw how to map something over a Maybe a, a list [a], an IO a etc. fmap :: (Functor f) => (a -> b) -> f a -> f b Getting our feet wet with Maybe Like this:

Related: