I've been gradually learning Haskell, and even feel like I've got a hang of monads. However, there's still a lot of more exotic stuff that I barely understand, like Arrows, Applicative, etc. Although I'm picking up bits and pieces from Haskell code I've seen, it would be good to find a tutorial that really explains them wholly. (There seem to be dozens of tutorials on monads.. but everything seems to finish straight after that!)
-
9You should look at the Typeclassopedia, it get many concept for Applicative and arrow (not sure about arrows). You can find it in [the monad reader issue 13](http://www.haskell.org/sitewiki/images/8/85/TMR-Issue13.pdf) – Raoul Supercopter Jul 14 '10 at 14:53
-
28Forget the exotic stuff. Write code. Only when you have written enough code will you be able to appreciate how the more exotic abstractions can help. And even then, you'll most likely get along just fine without `Arrows` and `Applicative`: there are getting on for 100k lines of code in GHC and we never even use monad transformers. – Simon Marlow Jul 14 '10 at 21:45
-
4@Simon: I understand your point, but do you really think it's a good idea to try to shut down curiosity about more advanced abstractions? I don't personally use Haskell primarily to get stuff done—I could work more efficiently in Java or Ruby. I use Haskell because it gives me new ways to think. I read the poster's question as being in this spirit—not about how to "get along just fine". – Travis Brown Jul 14 '10 at 22:14
-
5I think his point is that people think "Haskell" and think "academic abstractions", not "programming language". When you learn Haskell but never actually program anything, the cycle continues. Haskell is for writing computer programs, not for convincing your friends that you are smarter than them. – jrockway Jul 15 '10 at 01:06
-
2See the answer here: http://stackoverflow.com/questions/1012573/how-to-learn-haskell/1016986#1016986 – ShreevatsaR Jul 15 '10 at 01:10
-
7@Travis, my concern is that I think we risk driving people away from the language if we give the impression that you have to learn and understand these high level concepts in order to use it, that's all. – Simon Marlow Jul 15 '10 at 11:41
-
I feel like learning arrows is probably unneeded but learning Applicative is easy since it is a subset of monads and might as well be learned... – alternative Oct 13 '11 at 01:40
9 Answers
Here are a few of the resources that I've found useful after "getting the hang of" monads:
- As SuperBloup noted, Brent Yorgey's Typeclassopedia is indispensable (and it does in fact cover arrows).
- There's a ton of great stuff in Real World Haskell that could be considered "after monads": applicative parsing, monad transformers, and STM, for example.
- John Hughes's "Generalizing Monads to Arrows" is a great resource that taught me as much about monads as it did about arrows (even though I thought that I already understood monads when I read it).
- The "Yampa Arcade" paper is a good introduction to Functional Reactive Programming.
- On type families: I've found working with them easier than reading about them. The vector-space package is one place to start, or you could look at the code from Oleg Kiselyov and Ken Shan's course on Haskell and natural language semantics.
- Pick a couple of chapters of Chris Okasaki's Purely Functional Data Structures and work through them in detail.
- Raymond Smullyan's To Mock a Mockingbird is a fantastically accessible introduction to combinatory logic that will change the way you write Haskell.
- Read Gérard Huet's Functional Pearl on zippers. The code is OCaml, but it's useful (and not too difficult) to be able to translate OCaml to Haskell in your head when working through papers like this.
Most importantly, dig into the code of any Hackage libraries you find yourself using. If they're doing something with syntax or idioms or extensions that you don't understand, look it up.

- 138,631
- 12
- 375
- 680
-
4
-
1These are all good resources, but I think Okasaki's book is probably the most fundamental and also the most immediately useful. – John L Jul 15 '10 at 11:54
-
heaps of great links here, thanks! also thanks to everyone else's answers as well :) – guhou Jul 18 '10 at 10:34
-
3Updated links: [Typeclassopedia](http://www.haskell.org/wikiupload/8/85/TMR-Issue13.pdf), [Functional Pearl on zippers](http://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-fp/docs/huet-zipper.pdf). – kylc Aug 17 '11 at 05:41
-
Regarding type classes:
Applicative
is actually simpler thanMonad
. I've recently said a few things about it elsewhere, but the gist is that it's about enhancedFunctor
s that you can lift functions into. To get a feel forApplicative
, you could try writing something using Parsec without usingdo
notation--my experience has been that applicative style works better than monadic for straightforward parsers.Arrow
s are a very abstract way of working with things that are sort of like functions ("arrows" between types). They can be difficult to get your mind around until you stumble on something that's naturallyArrow
-like. At one point I reinvented half ofControl.Arrow
(poorly) while writing interactive state machines with feedback loops.You didn't mention it, but an oft-underrated, powerful type class is the humble
Monoid
. There are lots of places where monoid-like structure can be found. Take a look at the monoids package, for instance.
Aside from type classes, I'd offer a very simple answer to your question: Write programs! The best way to learn is by doing, so pick something fun or useful and just make it happen.
In fact, many of the more abstract concepts--like Arrow
--will probably make more sense if you come back to them later and find that, like me, they offer a tidy solution to a problem you've encountered but hadn't even realized could be abstracted out.
However, if you want something specific to shoot for, why not take a look at Functional Reactive Programming--this is a family of techniques that have a lot of promise, but there are a lot of open questions of what the best way to do it is.

- 1
- 1

- 76,893
- 19
- 209
- 302
-
+1 for backing up from `Monad` to `Applicative`, `Functor`, and `Monoid`, and I'd recommend in the reverse order (starting with `Monoid`). *Then* revisit *Monad* and check out `Arrow`. I bet you'll end up understanding `Monad` better for putting it into a wider context. There's a lot of magical thinking attached to `Monad`. It's just another type class, i.e., interface plus algebraic laws. – Conal Sep 13 '11 at 16:17
-
1@Conal: This answer is over a year old, and if there's anything I'd change in hindsight it would be to emphasize `Monoid` more heavily. It's probably the simplest structure that really shows the power of algebraic thinking and so much else is defined in terms of variations on monoids. I think I'd actually slip `Category` in alongside `Functor` or `Applicative`, though, despite leaving `Arrow` for later. – C. A. McCann Sep 13 '11 at 16:32
-
Thanks for the reminder about `Category`. I'm with you there. Simple & general. – Conal Sep 22 '11 at 02:53
Typeclasses like Monad
, Applicative
, Arrow
, Functor
are great and all, and even more great for changing how you think about code than necessarily the convenience of having functions generic over them. But there's a common misconception that the "next step" in Haskell is learning about more typeclasses and ways of structuring control flow. The next step is in deciding what you want to write, and trying to write it, exploring what you need along the way.
And even if you understand Monads, that doesn't mean you've scratched the surface of what you can do with monadically structured code. Play with parser combinator libraries, or write your own. Explore why applicative notation is sometimes easier for them. Explore why limiting yourself to applicative parsers might be more efficient.
Look at logic or math problems and explore ways of implementing backtracking -- depth-first, breadth-first, etc. Explore the difference between ListT and LogicT and ChoiceT. Take a look at continuations.
Or do something completely different!

- 38,665
- 7
- 99
- 204
Far and away the most important thing you can do is explore more of Hackage. Grappling with the various exotic features of Haskell will perhaps let you find improved solutions to certain problems, while the libraries on Hackage will vastly expand your set of tools.
The best part about the Haskell ecosystem is that you get to balance learning surgically precise new abstraction techniques with learning how to use the giant buzz saws available to you on Hackage.

- 3,771
- 23
- 16
Start writing code. You'll learn necessary concepts as you go.
Beyond the language, to use Haskell effectively, you need to learn some real-world tools and techniques. Things to consider:
- Cabal, a tool to manage dependencies, build and deploy Haskell applications*.
- FFI (Foreign Function Interface) to use C libraries from your Haskell code**.
- Hackage as a source of others' libraries.
- How to profile and optimize.
- Automatic testing frameworks (QuickCheck, HUnit).
*) cabal-init helps to quick-start.
**) Currently, my favourite tool for FFI bindings is bindings-DSL.

- 40,473
- 13
- 103
- 130
As a single next step (rather than half a dozen "next steps"), I suggest that you learn to write your own type classes. Here are a couple of simple problems to get you started:
Writing some interesting instance declarations for QuickCheck. Say for example that you want to generate random trees that are in some way "interesting".
Move on to the following little problem: define functions
/\
,\/
, andcomplement
("and", "or", & "not") that can be applied not just to Booleans but to predicates of arbitrary arity. (If you look carefully, you can find the answer to this one on SO.)

- 198,648
- 61
- 360
- 533
You know all you need to go forth and write code. But if you're looking for more Haskell-y things to learn about, may I suggest:
- Type families. Very handy feature. It basically gives you a way to write functions on the level of types, which is handy when you're trying to write a function whose parameters are polymorphic in a very precise way. One such example:
data TTrue = TTrue
data FFalse = FFalse
class TypeLevelIf tf a b where type If tf a b weirdIfStatement :: tf -> a -> b -> tf a b
instance TypeLevelIf TTrue a b where type If TTrue a b = a weirdIfStatement TTrue a b = a
instance TypeLevelIf FFalse a b where type If FFalse a b = b weirdIfStatement FFalse a b = a
This gives you a function that behaves like an if
statement, but is able to return different types based on the truth value it is given.
If you're curious about type-level programming, type families provide one avenue into this topic.
Template Haskell. This is a huge subject. It gives you a power similar to macros in C, but with much more type safety.
Learn about some of the leading Haskell libraries. I can't count how many times parsec has enabled me to write an insanely useful utility quickly. dons periodically publishes a list of popular libraries on hackage; check it out.

- 1,011
- 7
- 7