However, I find your tone particularly unpleasant. The sneer in "seem to be people who need worked examples of things to understand them" is repulsive. If this is a representative example of your community, it's one no-one should be proud to be a member of.
[1] http://www.maa.org/external_archive/columns/launchings/launc...
Its always good to apply the principle of good faith. You have no idea who you're talking to, are likely going in biased away from someones arguments, and this will be the first time you've ever conversed. On top of that you're hobbled by text. You also don't know if the writer is a native english speaker or not and might consider the phrase "seem to be people who need worked examples of things to understand them" entirely neutral in tone.
Communication is a 2 way street, the tone you perceive may not have been intended. And painting an entire group by one sentence, in one post, that you perhaps disagree with, is a bit of an overreaction in almost any circumstance. The tone you perceive is not one I've personally experienced, quite the opossite.
As a beginner in Haskell that is still learning, and learns best by examples, the gp's opinion on documentation drives me nuts. But by and large, most examples aren't all that necessary in haskell with the type system. But when you're learning, I have to say, I hate "the types will document everything" mindset. They tend not to when you're a stranger in a strange land.
I wouldn't say documentation itself is a problem in haskell, there is tons. I would say the problem is in quality documentation that at least recognizes audiences of disparate skill level would be at issue. Examples help, but if the examples use something like the state monad that you're not familiar with, it probably won't do you a lick of good to understand how to use it.
Haskell is hard to learn, or at least it was for me. There is a whole laundry list of concepts I had never even heard of that I had to understand before I could do anything real with the language. Some were apparently dead simple yet frustratingly abstract (e.g. Monoids). Some were intuitive but still took time to grok (e.g. list manipulation stuff). Some twisted my brain into knots and only yielded to persistent study and practice (e.g. monads with threaded state).
As I was working through all these "basics", I was constantly frustrated trying to write simple programs. I don't recall whether I blamed it on a lack of beginner-friendly documentation or not, but slowly it all started to resolve into a coherent picture and once I could consistently read and understand real-world types I found that the available documentation was almost always enough for me to quickly understand an interface and how to proceed in using it.
I think both sides of this debate are partly right. Haskell's learning curve seems to keep going up as far as you want to climb, and some of the stuff at the intermediate level IMO could really use more examples and documentation, or at least that was my opinion when I was looking at it a year or so ago. One good example might be Template Haskell, which pissed me off to no end every time I tried to use it even in very simple applications. It involves a lot of new syntax and concepts and IIRC had literally no documentation besides what Haddock gives you for free.
On the other hand, I think a lot of people criticize Haskell's documentation without knowing the language well enough to make use of said docs or even understand how they might be useful. IMO it's unrealistic to expect every module and library to provide documentation specifically for beginners who don't understand challenging yet ubiquitous concepts (like state monads, to use your example), and I don't think other languages necessarily do a better job at this, but Haskell is just so darn tricky to get your head around that the "total beginner" phase lasts way longer than it might in e.g. Python.
For beginners who do want to learn about the core concepts of the language, I found that there was plenty of material to help me on my journey: Real World Haskell, LYAH, the IRC channel, and the internet full of blog posts, to name just a few. I don't mean for this comment to cause offense, or to belittle anyone. I'm certainly not an expert Haskell programmer, and there is much that I still don't understand about it. I just wanted to share some insights I've had learning it and using it in some practical applications.
I think most documentation sucks and I dislike trying to read it, because it's very hard to get a picture of what's going on, and what these procedures / data structures / etc are really for.
I am much happier when I can just look at a straightforward and clear example, and then just use the documentation to look up specifics of how things work after I already get the basic idea.
It's not because I "need worked examples of things to understand them", it's because that is the way I like to work, because I have had many instances of my life of trying to make sense out of documentation that seems to have been written from a mindset of "formal writing involves not actually telling the reader what things are really for, straightforwardly". I don't know why that disease is so common, but almost all documentation is like that.
Counterpoint: this is what keeps me away from Haskell.
I really want to learn, and I really do appreciate the formal approach, but being able to do a few simple things quickly (driven mostly by intuition) helps fight frustration.
Haskell really does look great, but it's a bit... prickly.
Disclaimer: I'm very much a Haskell noobie
No, but for this case, type holes are much more powerful. You always have an I have X, I want Y, what functions are there that are X -> Y?
Hoogle is more powerful than anything I've seen on any other language. (If I could only make it use all the local packages, instead of the pre-built index. I'm sure there's a way.)
Haskell has also more need for documentation than most other languages, so hoogle is still not enough. That's the problem, not lack of docs.
I'm not, especially for the many more-abstract-concepts. I have yet to see a followable code case demonstrating the use of custom monads (not IO or Maybe or lists etc) that show why (when) I should ever write my own, to understand even just using them better generally.. A lot of explanations in the Haskell ecosystem are super-abstract and forever-self-referencing and as someone arriving with a sense of urgency of pumping out Brave New Apps to the world, I'm always itching and saying "OK transformables turn foldables that contain applicatives into functors that fold applicatives into transformables so in other words I CAN SKIP THIS RITE?" Leave it in the shadows as it was clearly a priority to neatly have the abstractions that allowed making MayBe/IO/Lists etc as usable language features in there.
On the other hand I don't want to end up writing 10k lines that could have been expressed in 500 had I grasped the more obtuse abstractions.
Experience tells me that once you happen across a simple real-world use, the shocking simplicity of what was encrypted in mathematical-logical-calculi lingo is instantly revealed. The absence of such "code examples" (with a real-world touch, not just x,y,z,f,g,h identifiers in a senseless vacuum) is truly annoying and goes all the way from the Wiki to Diehl's articles to various books.. it's hyperprevalent throughout the community.
For an interpreter I'm working on I have an "Eval" type, implemented as a newtype wrapper around a transformer stack. This gives me a context to work in where I can access variables in scope (carried in a ReaderT) and fail with error (handled by an ExceptT). The code (simplified) looks a little like this:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaExpr #-}
newtype Eval a = Eval (Reader EvalContext (ExceptT String m) a)
deriving (Functor, Applicative, Monad, MonadReader EvalContext, MonadError String)
lookupVariable :: Variable -> Eval Value
lookupVariable v = asks (findVarInContext v) >>= \case
Nothing -> throwError ("unbound variable: " ++ show v)
Just result -> pure result
lookupFunction :: FunctionName -> Eval ([Value] -> Value)
lookupFunction f = asks (findFuncInContext f) >>= \case
Nothing -> throwError ("unknown function: " ++ show f)
Just f' -> pure f'
evaluateFunction :: Function -> Eval Value
evaluateFunction (Function name args) =
lookupFunction function <*> mapM evaluateExpr argsI must admit that I can't remember ever creating my own monad from scratch.
Well sure, but if we're going to exclude those then the grandparent's ask is a bit high: either we present something useless and pedagogic, or we present something useful that exists in a library somewhere, or we present something new and useful... that we should then also put in a library somewhere!
That's completely baffling to me so I'd be really curious to hear your reasons (or those of someone who shares that opinion, as there are others in the thread apparently).
When learning about an abstract notion, it has been my experience that having good examples in mind (in the sense that they are not too complex, but non-trivial enough to illustrate the relevant aspect of the notion at hand) is very helpful, if not essential, for comprehension. All the more so for very abstract subjects (e.g. back in grad school I was studying algebraic geometry, and you can't go very far in that subject trying to prove things about functors on the category of rings without examples in mind that connect the abstract nonsense to some actual geometric meaning).
Speaking of abstract nonsense, by the way, under the Curry-Howard isomorphism, publishing a library with type signatures but no worked out example is equivalent to publishing a mathematical paper consisting entirely of lemmas with no example of how to combine them to prove something interesting (in fact, it's worse, because the expressiveness of the Haskell type system obviously pales in comparison to the language of mathematical papers). I would almost certainly reject a paper like that if I received one for review, and I expect most referees would too.
Python, PHP, etc... are incredible in that every single page of their standard library docs have fully worked examples. When you're trying to get things done, it's great to have a foundation to start from and see how others have done something.
I do notice that after a while, I can get more and more from types alone, but I would never get to that point without examples first.
----
I don't see why examples couldn't be type-checked though, so they never become out-dated – is there no way to do that with haddock?