Real World Haskell
book.realworldhaskell.org
book.realworldhaskell.org
1. It covers the core language pretty well.
2. It covers the secondary aspects even better. Including: Linking to C, performance analysis, parallelization, and a touch of compiler internals.
3. Written in a very readable tone, but assumes it's not your first time around the functional block. I picked up the pragmatic erlang book after this, and was put away at how much "baby's first functional language" it was in comparison.
4. Lots of examples in different areas: GTK, databases, networking, binary I/O. Grounds the reader coming from C/C++/Java land pretty well back in how to use the functional stuff for real work. Also shows that you can get all those tasks done with a good functional style, without mind bending.
So I would say: Want a book that'll have you learn Haskell fairly well and give you giant examples, but takes a week to read (or more)? Read RWH.
If you want to learn the basic language, w/o much example fluff, and learn the language in 2 days, read YAHT (linked in a comment below by me).
I skipped over the chapter about binary parsing the first time I went through the book because it seemed like pretty dull content. Later I returned to it, and about one-third of the way through it I found myself completely stumped and scratching my head. Out of nowhere they drop the state monad in your lap without really motivating it, or telling you what it is or warning you that most people find it a little bit difficult to wrap their head around at first.
At that point I was completely lost until a gathered together enough clues to go searching around on the internet for more explicit descriptions of what a state monad is.
1. Strong static typing
2. Pattern matching
(1) tends to make development go faster (in my experience) by catching your mistakes early and locating them more accurately than a debugger can. It's also good for performance.
(2) is great for any program that does a lot of stuff with trees, such as a compiler.
However, neither of these features is unique to Haskell. They're also present in OCaml, SML, F#, and Scala, all of which should be easier to learn and start using than Haskell.
The main qualities that distinguish Haskell from other languages are purity and laziness. These may be worth learning about since they're theoretically interesting, but their practical value is pretty dubious.
Purity is important if you care about safety, maintainability, or paralellism. Also makes transactional memory tractable.
I'm all for safety in the sense of catching errors at compile time, provided they can be caught with minimal help from the programmer. Proof of more complicated properties should be optional. Haskell requires you to embed a proof of functional purity into every program you write, and this is just not how programming should work.
As to maintainability, this claim is clearly false. Pure programs become harder to change as they grow, because adding and removing side effects requires drastic restructuring.
Of course, most Haskell programs (in my limited observation) seem to deal with problems that are mostly mathematical or computational in nature, like compilers and Sudoku solvers, where these issues don't arise much. But that's not really an endorsement for something that purports to be useful in the Real World.
Re adding and removing side-effects: I think you're just making this up without much experience. Most programs only need side-effects in certain areas, typically in the outermost loops and top-level functions. For example, a very simple single-threaded stateful web server could be implemented only needing I/O access in its outermost loop, implementing its request -> response function in a pure way, and using tail recursion to maintain state between different iterations of the server loop.
Re compilers: unless you've written several compilers, you can't make claims about techniques used in compilers not being highly useful in solving large classes of problems. In many ways, yes, compilers are the ultimate functional programs (output is a pure function of input), but guess what: the flow of a compiler - parsing input, inferring its semantic intent, performing required transformations and generating output based on recursive application of patterns - is exactly the same as the flow of an average web request.
The breadth of code on http://hackage.haskell.org/ gives witness to this, with just on 1000 libraries written over the last 18 months, most heavily weighted towards networking, graphics, guis, databases, and so on.
Similarly, the industrial users , http://haskell.org/haskellwiki/Haskell_in_industry , aren't writing sudoku solvers, but are finance houses, defense contractors, game companies, bioinformatics places, hardware dessign, a full range of applications, for a general purpose language.
If you're wondering where the idea comes from, here's an example. There is a thread on Facebook titled "What have you made using Haskell?"
http://www.facebook.com/topic.php?uid=2213713570&topic=2...
Here are the responses:
1. HAppS (a web thingy)
2. A minesweeper clone
3. A preprocessor for POV-Ray source files
4. A program to prove graph isomorphisms
5. A parser for boolean logic sentences
6. A lambda expression evaluator with alpha equivalence testing
7. A hyperbolic raytracer
8. An image regression program
9. A program that finds equidistant letter sequences
10. A boolean expression to truth table converter
11. A resolution theorem prover
12. An interpreter of a Prolog basic subset
13. A Markov Chain generator
14. An anagram generator
15. A library for doing computation inside various algebraic structures
16. A maze generator and solver
Some of these are exercises, some are toys, some look potentially useful. But except for the first two, they are all pure-functional problems, and are rather abstract. Maybe this sample isn't representative of all Haskell usage or what Haskell is capable of, but the stereotype, like most stereotypes, exists for a reason.
I am a relatively incompetent Haskell programmer and I am constantly amazed at how often algorithms I implement turn out correctly after I finally get them to compile.
It's an exaggeration to say that you must embed a proof of anything in your program. You just have to think a bit more carefully and explicitly about how your data is defined.
3. Higher-order types
(Yes, C++ has had this with templates for a while and Java has it with generics, but they bolted it on later, after the syntax and many essential libraries had been fixed.)
4. Type inference
Type inference is a REALLY BIG DEAL to me, because it makes programming in a strongly-typed language much less painful, and with that pain gone, I can better appreciate the compiler using the type system to cover my ass.
Even if I don't see it becoming the 'next big thing', I like Erlang, in that it's extremely practical for certain types of problems.
http://www.cs.utah.edu/~hal/docs/daume02yaht.pdf
Its much more technical but for programmers with experience in functional languages, its much quicker to jump in than "Real World Haskell"
(What I do know is that that is a very simple and beautiful site with a clever commenting system and selections from one of the most incredible icon sets ever made.)
http://www.zvon.org/other/haskell/Outputlist/introduction.ht...