
Introductions to advanced Haskell topics - davidkellis
http://www.haskellforall.com/2014/03/introductions-to-advanced-haskell-topics.html
======
exDM69
For any aspiring Haskell programmer out there, my advice is to stay away from
any blog posts describing Monads using analogies of some kind. The fact is
that you do not have to "understand" monads in order to write practical
programs that use the IO monad or even something more complicated like Parsec.
I've seen too many people stop using Haskell when it's time to start doing
something that isn't purely functional because they have been afraid of going
to unfamiliar territory.

Here's a simple two part exercise that should give you enough of an
understanding about the basics of using IO and give you a general idea about
monads.

    
    
        1. Write a "guess the number" game
        2. Write it without "do" notation, using (>>=)
    

That's it. If you're at all like me, this should give you a better start than
reading theory about the subject. Now that you have a basic understanding
about the practice, it's easier to grok the theory.

And even if you do not understand the theoretical aspects of it by now, you
know enough IO to be able to read and write files, connect to the internet
using sockets or do some HTTP requests. That opens a lot of possibilities.

~~~
Buttons840
I've found these Haskell slides useful:
[http://dev.stephendiehl.com/hask/](http://dev.stephendiehl.com/hask/)

The slides suggest an "Eightfold Path to Monad Satori":

1) Don't read the monad tutorials. 2) No really, don't read the monad
tutorials. 3) Learn about Haskell types. 4) Learn what a typeclass is. 5) Read
the Typeclassopedia. 6) Read the monad definitions. 7) Use monads in real
code. 8) Don't write monad-analogy tutorials.

I've found this advice helpful. Monads are something you'd probably invent
yourself once you know the rest of the language well enough.

~~~
JoshTriplett
> Monads are something you'd probably invent yourself once you know the rest
> of the language well enough.

Very true. I understood monads far better after I wrote some explicitly state-
threaded code (where every function took a state and returned (state,
actual_return)), wrote functions equivalent to >>= and return, and then turned
the result into a monad.

~~~
ndeine
Better yet, isn't that what the State Monad[1] is doing internally?

[1]:
[http://www.haskell.org/haskellwiki/State_Monad](http://www.haskell.org/haskellwiki/State_Monad)

------
jdreaver
The first two monad papers, "You could have invented monads" and "Monadic
Parsing in Haskell", are terrific.

I think that monads and most monad tutorials are great examples of "this
concept is hard because everyone says it is." It reminds me of engineering
school, where a lot of people sit around and complain about how hard something
is _instead of actually trying to do that particular thing._ Monads really
aren't super difficult to grasp, and I wish people would stop making tutorials
that only serve to confuse learners more.

~~~
platz
I think monads may be intimidating at first because it involves an unfamiliar
abstraction, and all abstractions take some getting used to.

The good news is since they _aren 't_ complex, once you understand the
abstraction, it appears to be very simple in retrospect.

[http://byorgey.wordpress.com/2009/01/12/abstraction-
intuitio...](http://byorgey.wordpress.com/2009/01/12/abstraction-intuition-
and-the-monad-tutorial-fallacy/)

~~~
progman
Wikipedia has a pretty good analogy explanation. I like the idea of monads
being "programmable semicolons" which are used to inject side effects between
purely functional applications.

So if I understand monads correctly then they are basically functions that
work like a Unix pipe between functions which takes input data in a monadic
container, performs some side effects (I/O for instance), and yields another
monadic container with output data that is forwarded to the next function -
all that without violating the purely functional character of the whole
application chain.

[https://en.wikipedia.org/wiki/Monads_in_functional_programmi...](https://en.wikipedia.org/wiki/Monads_in_functional_programming)

~~~
dllthomas
_" they are basically functions that work like a Unix pipe between functions
which takes input data in a monadic container, performs some side effects (I/O
for instance), and yields another monadic container with output data that is
forwarded to the next function - all that without violating the purely
functional character of the whole application chain."_

That much is true of any applicative functor (which is a superset of monads).
The additional power monad gives you is to change up the later portions of
that chain based on the earlier results.

Of course, a lot of uses of "monads" don't really make the distinction (and
applicative functors are plenty useful).

------
egonschiele
> none of them clearly explain how lenses work

I had taken a stab at this with my lens tutorial[1]. But if you just want to
use lenses, Joseph Abrahamson's posts[2][3] are much better. And of course,
SPJ's talk is great. He's an excellent public speaker.

> I'm really disappointed that so many critical Haskell topics only have a
> single source of truth that is difficult to find.

I found the same thing when I started learning Haskell a few years ago, so I
started a blog on advanced topics[4]. Since then there have been a _lot_ of
excellent haskell posts. In particular, Stephen Diehl[5] and Christopher
Done[6] write interesting and easy-to-read posts. The School of Haskell[7]
also has advanced, interactive posts by very smart Haskell folks. So this
problem is not as dire as this post makes it sound.

[1] [http://adit.io/posts/2013-07-22-lenses-in-
pictures.html](http://adit.io/posts/2013-07-22-lenses-in-pictures.html)

[2] [https://www.fpcomplete.com/school/to-infinity-and-
beyond/pic...](https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-
of-the-week/basic-lensing)

[3] [https://www.fpcomplete.com/school/to-infinity-and-
beyond/pic...](https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-
of-the-week/a-little-lens-starter-tutorial)

[4] adit.io

[5] stephendiehl.com

[6] chrisdone.com

[7] fpcomplete.com/school

~~~
verroq
All you need for lenses is SPJ's talk
[https://www.mediafire.com/?ra37c2948pw2ye6](https://www.mediafire.com/?ra37c2948pw2ye6)

------
AnimalMuppet
I think that monads are hard for non-functional programmers to grasp for two
reasons: They take a different way of thinking, and "monad" is the wrong name.

"The name is wrong?" the Haskell crowd replies. "Not at all! Look at the
function signatures, and look at the definition of a monad in abstract
algebra! It _is_ a monad!"

Well, any function with the signature a -> a -> a is a magma (per abstract
algebra), and those are all over the place in Haskell. But we don't hear much
about magmas in Haskell. We _do_ hear a lot about monads. Why? Because monads
are magic in Haskell, and magmas are not.

But here's the thing. Monads are magic for reasons that have to do with
programming in Haskell, but that really don't have much to do with abstract
algebra. _That 's_ why it's a bad name. It's like I told you that something
was "an enumerable set of bricks" rather than "it's a three bedroom house".
"An enumerable set of bricks" is in fact an accurate description, but it is
not a useful one.

~~~
thinkpad20
I agree to an extent, but I think it's a minority opinion. I had a similar
point to make about monoids, and would rather see them called "addables" or
something similar. Yes, yes, I know, they're not just about adding things...
but a great majority of times, `mappend` is used as an adding operation, or
something similar (union of sets, concatenating strings, etc). But I didn't
receive much support for this view, because "look at the definition of a
monoid in abstract algebra! It is a monoid!"

It's this kind of thing that makes Haskell so cool, but also makes it so
unlikely that it will ever see real widespread adoption. Haskell is a language
based heavily on mathematical theory. There's more of a focus on expressing
mathematical concepts and hewing to theoretical correctness than on being
practical. Why are there no (real) exceptions in Haskell? Because you can do
it with monads. Why aren't there member variables on objects? Because you can
do it with functions (or better yet, lenses! a shiny new abstraction to
learn!). Why is there no stack trace when a runtime error occurs? This one I
don't have a good answer to, but I think it has to do with laziness, which has
its roots in theory as well.

I love Haskell and have written several large projects in it. I write it
almost every day, currently in the middle of a project with ~1,500 lines of
code written over the last month or so. But a lot of it feels like bending
over backwards to allow features that would be completely basic in other
languages, because of the thing I was talking about above: the _starting
point_ is the theory, and the practical comes after. The names of the types
are just the tip of the iceberg on this one. There are many great and
practical libraries for Haskell (some of which this post's author has
written), and many are incredibly powerful, expressive and performant, so it's
wrong to say that Haskell isn't "for the real world". But it's really a whole
different philosophy than 90% of other languages.

All that said I'm not sure I can come up with a better name for Monad.
Context? Pipe? Container? Nothing really springs to mind. It's sort of its own
ball of wax.

~~~
tel
I think Haskell as a community favors more learning over having edges to
abstractions. You could call Monoids "Addables" and it would make intuitive
sense more quickly, but it would (a) face edge cases later (multiplication is
a monoid, as is "take the leftmost argument") and (b) not link to a larger
literature of abstract algebra.

That turns a lot of people off, as you mention, since they want the names of
things in their language to provide immediate (partial) intuition as to what's
going on.

The upshot is that reading Haskell expects more background literature in
abstract algebra (or at least a willingness to read the docs for a while to
learn a new vocabulary) but suffers fewer intuition breakdowns.

I think that's a general theme of the style of Haskell programming—suffer few
intuition breakdowns. It's reinforced by purity, equational reasoning,
sophisticated types, top-level annotation style, some parts of laziness, etc.
Altogether these pieces fit together to form something unique and interesting.

So that tradeoff of immediate understandability is painful. The community is
battling it by (increasingly) building more and more public documentation.
Without that tradeoff Haskell wouldn't be as unique and specialized, though.

~~~
thinkpad20
Yeah, I agree. Haskell has an almost unmatched capacity for abstraction and
high-level thinking. This can be a double-edged sword, but it has made Haskell
pretty much in a class of its own, and a very special language.

------
pash
An introduction to type-level programming should also be on the list, I
think—but there are no great blog posts yet about newer type-system extensions
in GHC, as far as I'm aware.

You can find some good posts on older techniques and features (phantom types,
GADTs), but there's not much out there introducing type families other than
material riffing on the papers that introduced them. (The papers are usually
quite readable, with well chosen examples, but ...)

For example, there's almost nothing beyond the docs about the tweaks in GHC
7.6–7.8 that make doing computation at the type-level easier. Different type-
system extensions can get you many of the same places (e.g., GADTs v. type
families, particularly the new closed variety), and I haven't seen much advice
about when to prefer one variation to another (hint: it usually helps to think
about type-function injectivity/non-injectivity and definitional
openness/closedness).

Richard Eisenberg's blog [0] might be the best source of insights on this
stuff right now, but as a researcher he's often out closer to the bleeding
edge than best suits a beginning type-level hacker.

\-----

Another topic with poor coverage: Template Haskell.

\----

Roman Cheplyaka's post about monad transformers [1] is one of my favorites, by
the way. More code than prose, and it's not a from-the-ground-up tutorial, but
if you understand the examples, you will understand transformers and why they
are actually useful in real-world code.

\----

0\. [http://typesandkinds.wordpress.com/](http://typesandkinds.wordpress.com/)

1\. [http://ro-che.info/articles/2012-01-02-composing-monads.html](http://ro-
che.info/articles/2012-01-02-composing-monads.html)

~~~
habitue
Ezyang recently posted about "Haskell for Coq Programmers"[1] which I think
explains the limitations of type level programming in Haskell pretty well. It
made a lot of sense to me because it explains the features coming from a
language with a more expressive type system and what capabilities Haskell has.

[1][http://blog.ezyang.com/2014/03/haskell-for-coq-
programmers/](http://blog.ezyang.com/2014/03/haskell-for-coq-programmers/)

------
platz
Simon Peyton Jones took a stab [sic] at explaining lenses in a down-to-earth
way

[https://skillsmatter.com/skillscasts/4251-lenses-
composition...](https://skillsmatter.com/skillscasts/4251-lenses-
compositional-data-access-and-manipulation) (log in to view)

~~~
T-R
This was a fantastic talk. Sad that you have to log in to view it now. That
was definitely not the case a few months ago.

------
ninjakeyboard
Good post - I book marked this. As a scala dev, I find higher kinded types
hard to approach and find practical uses. I'd like to get into haskell just to
improve my ability to work in functional programming in the industry as a
scala developer. This post was much appreciated.

------
dcre
This is great. I love this kind of documentation/tutorial roundup post.

