This is an amazing book. I highly recommend it as the first Haskell book you read. After it, you can check out Real World Haskell.
To elaborate on why you shouldn't read (at least the online version of) Real World Haskell first: It has a lot of important topics that it covers that LYAH does not cover (like how to use cabal their package manager). But, it's not as good of a tutorial on the language and functional programming. It glosses over very complex topics, goes into a lot of depth on details that are not so important and worst of all, gives you some exercises that you aren't capable of answering yet. I tried learning Haskell three times from that book and gave up because it just killed my confidence.
Then I discovered LYAH. It explains things very simply and at a very good pace. If you want to learn Haskell and/or functional programming, I can't recommend it more. Imagine one of the Head First books without all the corny. The only thing I wish it had was exercises.
I started reading the online version, enjoyed it so much, I went ahead and boug ht the treeware version. And it's awesome.
I felt so loved as a customer of No Starch Press. They sent me the book, let me download the ebook in three free formats (no DRM), plus I got a bunch of freebie stickers.
The book itself is also quite remarkable to me in that I can read it and understand Haskell without needing a computer. I am used to reading mathematics books, and while I don't think Haskell is a programming language for all mathematicians as is so often advertised, the language does have a certain appeal to it in that you can treat its programs as abstract exercises that you can do independently of a machine. The statelessness of the whole thing doesn't need me typing stuff into a machine to see what a particular line of code. This makes it great for offline reading, away from the computer.
So yeah, get the treeware version. Support your favourite authors. :-)
What I find confusing with Haskell is that the keywords don't seem to be consistent with the concepts they're meant to express. As someone new to Haskell I learnt that the `class` keyword doesn't express the object-oriented concept of class, but the concept of type class, which is different. Fair enough. What about declaring types then? That must be `type`, right? Nope, `type` is for creating type aliases. OK, surely that must be `newtype` then? Wrong again, `newtype` is also for declaring aliases. All right, to declare a new type, you don't use `newtype` nor `type` you use `data`. But be careful, the part that has the `data` keyword is still called a type constructor, whereas the part that does not have the `data` keyword is called a data constructor.
OK so let's recap, you create a new type with `data`, which is formed of a type constructor that starts with the keyword `data` and a data constructor which doesn't start with `data`. To create aliases you use `type` and `newtype` and to create type classes you use `class`.
Now how do you call the type class of things that can be mapped over? Surely that must be something like `mappable`?
The designers of Haskell (and Haskell is one of the few successful design-by-committee languages,) were not doing things "your way" (where I assume you are a working programmer, with knowledge of some or even many traditional imperative languages.)
They were PL researchers. Used to ML, Common Lisp, Ada, and, most importantly, Mathematics and Category and Type Theory.
`data` introduces an algebraic data type, so it makes sense to use data as a keyword. `type` and `newtype`, on the other hand, are programmer's conveniences: both carry no runtime cost, they are not actually part of the semantics of the backend language.
`map` is a function that's really just a specialization of `fmap`. Now, my category theory is a bit weak, but if I'm thinking correctly here, `fmap f` is an endofunctor in the category of functors, and so it makes perfect sense to call "mappable" Functor. There's also "Traversable," which works pretty much like a fully-fledged "mappable" with all extras, but also requires a Functor instance.
Keywords, and idiosyncrasies of a syntactic nature are really just superficial. The actual elegance of the language is its type system. (The actual warts of the language are, for the most part, also in the type system; records for example.) The latter criticism about `mappable` is really just due to the fact that you haven't gotten used to the underlying theory (and I don't blame you, it's hard.) But getting used to it can be rewarding. I'm not saying it's going to make you a better programmer (I'm not necessarily of that opinion,) but it's rewarding in its own right.
Oh, and the difference between data constructors, type names, and, later, kind names (with promotion, since 7.4,) can be confusing. I sometimes find it an oversight that they are not distinguished syntactically, I think that would greatly help most newbies, and sometimes even make things easier to read and understand for veterans, too.
Huge mistake on their part, typical of math people.
High level programming languages have to be as close as possible to human languages (English) not to some obscure mathematical concepts and notation that most people don't care about. Actually math notation itself (cryptic, inconsistent, ambiguous) is a horrible result of math people's communication handicap and ineptitude.
No. The math notation that is used across all branches of mathematics is consistent and unambiguous (the notation of formal logic, naive set theory, etc). The only ambiguity typically comes from traversing different branches of the discipline, which is inevitable considering how many branches there are and how deep they go.
Furthermore, mathematics is all about communication. The language of mathematics exists to codify concepts so that they can be talked about concisely. Being able to say 'group' instead of 'set with an associative binary operation with identities' is essential if you want to be able to build on top of that concept without taking an hour to read one theorem.
The handicap in communication isn't on the mathematics end, it's on your end. You seem to expect them to be able to explain structures to you that took years of work to build by using the same language that you use to talk about sports or social events. The reality is that you are not the target audience of their communication, and they are okay with that. You should be too.
The weirdest assertion that you made is that high-level programming languages ought to be as close as possible to human languages. The two categories of languages exist to communicate fundamentally and widely different groups of concepts. Words represent categories of analogous concepts, and the relevant categories in human life are nothing like the relevant categories in programming. In Haskell, 'functor', 'applicative functor', and 'monad' are highly relevant categories. They pop up everywhere and can be leveraged with great benefit. In human life these concepts are far less common, and thus do not merit words in the common vernacular. Were we to use a programming language modeled on English, we would miss the benefit of these abstractions, trading them for categories like 'dog' and 'car' which have very little practical use in typical programming.
>>No. The math notation that is used across all branches of mathematics is consistent and unambiguous (the notation of formal logic, naive set theory, etc). <<
Nonsense. Actually, ambiguity starts with basic arithmetic.
Take multiplication for example. We have several kinds of notation for it. Which is inconsistent. In the case of juxtaposition, it's ambiguous because two or more juxtaposed letters don't necessarily imply multiplication. And I'm talking about arithmetic only. Then, ambiguity only builds up. Cross product, Dot product & crap.
>>>Being able to say 'group' instead of 'set with an associative binary operation with identities' is essential <<<
OK, but the word "group" should be used for no other meaning...
>>>The reality is that you are not the target audience of their communication, and they are okay with that. You should be too.<<<
As you can see pretty much anyone is the audience of some math and its inconsistency and ambiguity. It just varies the level and the amount of it.
>>>The weirdest assertion that you made is that high-level programming languages ought to be as close as possible to human languages. The two categories of languages exist to communicate fundamentally and widely different groups of concepts. Words represent categories of analogous concepts, and the relevant categories in human life are nothing like the relevant categories in programming. In Haskell, 'functor', 'applicative functor', and 'monad' are highly relevant categories. They pop up everywhere and can be leveraged with great benefit.<<<
False. Computers and software are mainly used to emulate some real world stuff (objects, actions etc.) and to help people with real world stuff in a more automated way.
They aren't used too much to prove theorems or some other math stuff. And pretty much no one cares about proving the so called "mathematical correctness" of a program - a concept that doesn't even make sense in most cases.
Old misconception among FP advocates, even Dijkstra himself admitted that he was kinda wrong about how computer would evolve and what they'd used for. But the associated misconceptions live on.
A language close to human language also helps avoiding errors. That's why you won't see functional languages in critical systems, but rather languages like Ada which is probably the closest programming language to human language. The claims of clarity of FP languages are pretty much at odds with the evidence the real world provides.
A programming language can be created such that it resembles a natural language but it also avoids the ambiguities of that natural language. Anyway, the main idea is that FP languages are way too cryptic and ambiguous, they use too many symbols with multiple meanings which don't make any logical sense at a first glance. If you have to go to great lengths to explain the meaning of a simple symbol, then its use is wrong in a language that is claimed to be general purpose, clear, easy to read and so on. Either that, or the language is not general purpose and/or doesn't have those claimed qualities (clear, etc.) in a general sense.
Or, you simply have not learned enough yet to understand the language. Programming languages are not designed to be easy to pick up with no prior knowledge, they're designed to be powerful when used by professionals who actually know what they are doing.
If you're going to make the claim that functional languages use ambiguous symbols, you're going to need to back that up with some examples. I find it exceedingly hard to believe that there is any ambiguity in the operators of a statically and strongly typed language like Haskell.
Or, maybe the language is very poorly designed. There are many programming languages. From Basic to LISP to C to Java to Haskell to ... Brainfuck. Some of them are used in the software industry and some are not. There are many claims about many languages: language x is good because [insert some random ramblings], language y is good because [...]
However, no language is adopted by the industry solely based on claims (and btw. I have seen some utterly ridiculous claims made by those who try to promote Haskell.) Every once in a while, some companies try out new languages.
Very few such languages get adopted and as you can see functional languages are almost completely absent from the industry. And there's a very good reason for it: they're simply not suitable for producing professional grade commercial software. If it had been otherwise, someone would have figured it out. The funny thing is that the start-ups that try to use them (usually founded by FP advocates themselves) also fail one after another. But some people never learn. Furthermore, many companies forbid the use of functional style or characteristics implemented in certain imperative languages. The code of good, proper lanaguages for general purpose software engineering, is almost self describing! What is unclear should be sorted out quite easily using the documentation.
Those "professionals who actually know what they are doing" don't seem to exist when it comes to functional languages. The evidence is the very fact there's not a single piece of important commercial software written in such a language.
The question is rather: can such specialists exist? Because I'm afraid they can't exist because the functional approach is fundamentally wrong.
Examples of ambiguity in FP?
What is the following line supposed to mean and what part of it suggest anything about that:
a b c
How is ~ an intuitive replacement for minus? How is (* 5 5) supposed to be as clear as 5 * 5 ?
ps. dynamic typing and type inference are two awfully bad things and either of them can lead to trouble in large programs
I don't think it's ever a mistake for something to push standards higher, even if those standards are so high that it might turn off some talented people.
I also disagree overall with your assessment of mathematical notation. But it doesn't really matter because Haskell doesn't actually use any math notation. It does use some math terminology, though, and overall mathematicians are absurdly pedantic about terminology. Mathematicians may not be great at telling jokes at parties (though you may be surprised!), but it's their job to make sure they are writing in consistent and unambiguous ways.
This depends on the point of view. I expect to find a rather high standards in Haskell programs than, say, Ruby, for exactly the same reasons you've mentioned and I think it's an awesome feature, quite the opposite to a mistake.
And yes, I am a "real programmer" and don't use Haskell at work myself (for the run-time performance reasons).
Scheme, Clojure, and most of Erlang are on an entirely different side of a fairly large chasm within the lay term "functional programming". Haskell, ML, Ada, Coq, and even some parts of Scala are just entirely different beasts. The underlying math is far more pronounced, leadi to new terminology and power.
Ada?! It's purely imperative, type-safe language, no? At least that was the impression I got when it was forced on me at university.
Also, ML? I know OCaml a bit, but according to this comparison: http://adam.chlipala.net/mlcomp/ Standard ML has a "ref" type, which in effect allows mutable state. While it lack a bit of a syntactic sugar for this, OCaml's mutable record fields are implemented in terms of refs, so in the end SML isn't "more functional" in this than OCaml. Also, according to this answer (didn't check specs) SML has at least a WHILE loop: http://stackoverflow.com/questions/818324/loops-in-sml-nj which is typical to imperative languages. OCaml makes no attempt to outlaw side-effect (I suppose SML is similar), it allows them explicitly by introducing functions which return () (unit type), which are called purely for their side-effects. There is even List.iter function, which accepts a function executed for each element only for side-effects. And side-effects are not restricted in any way.
On the other hand Erlang has nothing like that - no loops, no mutable state in the language and it's side-effects are restricted to message passing.
While Scheme and Clojure, too, allow mutable state and non-pure functions, the default is immutable and pure for almost everything. In Racket the most used data-structure, a pair (and lists by extensions) is immutable by default and all the functions working on pairs and lists are pure. There is another type, "mutable pair", which is used to construct mutable lists, but I haven't seen it used yet.
Coq is not even turing complete.
Anyway, I much prefer talking about "functional style" than "functional programming"/"functional languages". If you think that one cannot use monads outside of Haskell - you're wrong. The same applies for lazy evaluation, which is available in many languages as extension or special syntactic construct in the language itself.
EDIT: I realized that parent probably thought of AGDA instead of ADA. And so I just installed it to check it out :)
I use Ada (a proper noun) regularly. It is not a functional language, but encourages a lot of the same things that functional people like to talk about. Ada is a wonderful language to use. It's rather boring and uneventful and is not accompanied by buzz words, but most of the Ada folks I know (converts or otherwise) all suggest that they're accomplishing more in less time with fewer bugs than they get with other languages. A lot of the new, buzzy languages seem to be solving problems that Ada took care of in the 80s and 90s. It's definitely worth a look if only to improve your approaches to software.
Haskell looks very interesting but I can't help but ask 'why do I need it?'. Currently I am learning Java since I want to get a jr.developer job later on and Ruby for some scripting and personal projects(maybe even Rails later). So Java is used in industry, Ruby is used in web and metasploit/ronin (something that I like to mess with), but what about Haskell? I am genuinely curious what Haskell can offer. I always see it mentioned on Reddit but I have yet to come across any notable project written with it. Could somebody with experience give me some reasons for me to learn it?
You don't need it. If you are a Junior developer (or aiming at being one) Haskell is a language you most definitely don't need.
Now, once you have your feet wet, it's worth learning. Here's why:
- Pure(mostly) functional language. This is in opposition to Java & Ruby, which while having functional aspects are OO (Object Oriented).
- It's okay not to know what a functional language is. It's making functions first-class citizens, such that a function becomes a value like any other.
- Separates IO from computation. IO is inherently impure and unreliable, so functions are generally pure and instead wrap IO in containers. Obviously, programs would be less useful (still use in the compiler running!) without IO.
- All of these concepts (and more) will change how you think about programming and make you a better programmer in all languages.
Haskell can be found in some backend stacks, the more notable examples I can think of are Mailrank (acquihired by Facebook) and Bump.
Personally, I've only done a limited number of projects with Haskell (a Postgres-backed beer API & IRC bot) but I've grown to respect it as a language and through limited exposure has made me love FP.
Functional programming is really more than first-class functions. A lot of languages have support for first-class functions (including Ruby's procs) that are not really functional languages. Functional (like all paradigms) is a bit nebulous, but to really be a functional language I would expect to see immutability as a default assumption, and I would expect to see only expressions, no statements. That latter expectation is really what gives functional programming its distinctive style. When everything returns a value, chaining together functions as transformations on data simply becomes the natural way to program.
To amplify what another has said, the emphasis of functional programming is side-effect-free code, where the default assumption is that functions don't have side effects, and so can be treated as components in a pipeline that modifies data step-by-step from its initial input state to its final output state.
Ideally, these components are composable and reusable, both to facilitate reasoning about the code and code reuse. The Haskell Standard Prelude is a fantastic example of this working out well.
Basically, it's based on the idea that the functions which are easiest to reason about are those with one well-defined input and one well-defined output which is completely determined by that input. You can't always have this, but functional languages attempt to get you as close as possible. The simplicity of pipeline-style programming is one of the happy little dividends of this kind of thinking.
From the perspective of "learn other languages to broaden your horizons":
Haskell is worth learning because it has an expressive, strong, static type system. Most other languages do not have that property (Java's type system is static, give or take null, and strong, but not expressive, and Ruby's is strong but neither expressive nor static). The Haskell type system lets you have conversations with the compiler about what your program should do.
You can declare a state type, and have the compiler tell you if you switch on the state and forget to handle one of the possible states (or if you add a state later and forget to update all the switches).
You can tell the compiler "I think this function is a generally useful utility function that I plan to extract out of this project and use elsewhere", and it will tell you whether there's some dependency on your project that you missed.
You can specify in a function's type "this function should have access to the database"; then the compiler can tell you if you're trying to access the database somewhere you didn't expect to. (A colleague has just spent a person-year of effort refactoring a Django web app, because all the database calls were happening in the view code, and they needed to abstract them out to scale.)
Of course there are ways to do some of those things in other languages, and of course there are also downsides to the static type system. But those sorts of abilities open up new programming techniques (even in languages with poorer type systems), and have shown me ways programming can be better.
>I've heard of a language being called expressive, but not a type system.
Haskell's type system is practically a language itself. It has many powerful features that aid with expression:
* sum, product and generalized algebraic data types (GADTs)
* higher-kinded types
* universally & existentially quantified types
* scoped type variables
* impredicative types
* associated types
* type families
* kind polymorphism (a new feature)
* type holes (also new)
>By the way, does Haskell's type system have the "value restriction" that you run into in ML?
I'm not sure what you mean by "value restriction". Haskell, like ML, is not a dependently typed programming language. For that you'll want to use something like Agda. As for why you'd want a language to not have dependent types? Well, having them introduces all kinds of considerations with regards to decidability and type inference.
The value restriction is a rule that governs when type inference is allowed to polymorphically generalize a value declaration. In short, the value restriction says that generalization can only occur if the right-hand side of an expression is syntactically a value. [...] The value restriction prevents a ref cell (or an array) from holding values of different types, which would allow a value of one type to be cast to another and hence would break type safety
It can be annoying to work around this, because there are potentially ML programs that would be type-safe and would otherwise compile if they were not hindered by the value restriction.
I got my answer, though:
Ii is interesting that in ML, the presence of mutable ref cells and parametric polymorphism requires the whole language to be dominated by a "value restriction"  to ensure that the type system remains sound, whereas in Haskell, because IORef's can only be created (and used) in
the IO monad, no such restriction is necessary.
There are two very different types of arguments typically made as to why to learn the more esoteric languages (Haskell, Lisp, Forth, others).
The first is the more common: learning these languages exposes you to other ways of programming, which in turn makes you a better programmer no matter what language you're programming in. This is unquestionably true. Mainstream languages are constantly learning new things from these languages, which means you will be able to apply the techniques you learn from them to your code no matter what language you write in. I have the misfortune of writing a lot of PHP at my day job, but it turns out even PHP has support for filter and map over arrays. If I hadn't learned functional programming, I would never have even looked for them.
The other argument, which is made less often, is that you can actually write great software in these languages. This argument is made less often because we can obviously look at the market and the TIOBE index and see that Haskell is way down at #30 with 0.323% of the market share. However, there are really great programs made in Haskell (xmonad, for one). There are also tons of great programs made in Lisps, especially Clojure of late. So, this second argument is not entirely a dead end either.
Revisiting something I mentioned in the first argument for a moment though, I would actually make a third argument that I rarely see. As I said, other languages are constantly learning new things from these languages. Haskell's community is full of PhDs studying at the intersection of programming and mathematics, and they are discovering the things that will revolutionize programming in the future. Haskell, for example, has been exploring strong static typing with algebraic datatypes, Hindley-Milner type inference, and typeclasses to support higher-kinded polymorphism. Those concepts are turning out to be incredibly powerful, and you will inevitably see them in other programming languages in the future. We've seen this before with Lisp (garbage collection, recursion, first-class functions), and there's no reason not to expect the trend to continue.
So, why learn Haskell? It's the easiest way to see what tools you'll have available to you in industry 20 years from now when the other languages catch up.
Which is a fantastic book, clearly written as a labor of love.
Erlang doesn't have Haskell's type system and doesn't seem to be of much interest for CS research types, but it's awesome for developing certain kinds of system.
I am curious about Haskell myself, and don't tend to need a lot of excuses to learn a language, but I don't perceive a "sweet spot" for it just yet, as in "I could go build X, and Haskell would be a great fit for it". Given how many smart people use it, I'm sure there are a lot of applications for it, but I also get a feeling that there's not one thing that really stands out.
One thing that I love to do in Haskell, and which Haskell is especially suited to, is writing interpreters and parsers. The other week I wrote a brainfuck interpreter (https://github.com/imeckler/skellfuck) in a couple of hours. Parsec, along with monads and functors, make this kind of thing a real joy to write.
It's a tiny detail but learning some functional ways of thinking gives you great alternatives to for/foreach loops when dealing with large lists/arrays/hashtables of data, even in other languages like Ruby or Java.
For the same reasons you need any programming language—to write useful software in!
> Currently I am learning Java…and Ruby
These are both good ideas. Java is widely used, reliable, and well tested for developing large applications. Ruby is simply a lot of fun to use, and one of the things you’ll discover while using Ruby is that it places a lot of functional programming idioms in an object-oriented context.
The issue with many popular languages is that they fall into much the same paradigm, namely imperative and either procedural or object-oriented, with some functional features borrowed for working with lists. It’s worthwhile to see that not all languages are like this, and learning a new language is not just about new syntax and APIs.
> but what about Haskell? I am genuinely curious what Haskell can offer.
Haskell will teach you to think about structuring your program in terms of simple data and transformations on that data. Object-oriented programming is about coupling data with behaviour, whereas a big part of learning Haskell is learning how to recognise high-level patterns in data structures and functions separately. In doing so, you can avoid the work of reimplementing common operations yourself.
You begin to say, oh, this is a data structure I can map a function over; I’d better make it an instance of Functor. And hey, I could use this data structure to represent this kind of computation, maybe it should be an Applicative and a Monad so I get some nice syntax for dealing with it. This function has a type signature that looks an awful lot like that other type signature—I wonder if I could implement one in terms of the other? And so on.
The type system and succinct syntax also make it very easy to create new data types, and you learn how this can help avoid bugs—don’t use a Boolean here, use an enumeration with two values; then you can’t mess up. Java discourages this by requiring more syntactic effort to create a new datatype.
A useful and oft-cited example of this is in the context of web frameworks: if you have separate data types for strings and HTML, that one simple thing eliminates a whole class of injection attacks. If you represent your links in the type system, then you can statically ensure that your site does not have any broken links. Simply put, quite a lot of bad things can be caught at compile time if you have a type system expressive enough to talk about them.
> I have yet to come across any notable project written with it.
There are more notable projects out there, but here’s my self-promotion. At my old job I maintained a compiler for ActionScript 3 in Haskell, as well as a build system that coordinated the compiler and other build tools to convert Flash games to iOS and Android applications.
Haskell is excellent at manipulating data structures—if that sounds ridiculously general, that’s because it is. The compiler is very nearly feature complete and, even with a certain amount of technical debt, was an order of magnitude smaller and easier to refactor than it would have been in an imperative language.
So there you go. From a recovering professional Haskeller, why you should learn Haskell. And, for that matter, the answer to “should I learn this language?” is always “yes”; but some languages should be higher on your list than others. ;)
Haskell can offer absolutely nothing Java can offer, while Haskell can't offer even 0.001% of what Java offers.
You see, there's a very, very good reason why you won't see any (even remotely) serious and useful software made in Haskell and why you won't see it used by companies (which means that jobs are literally extremely close to zero)
Haskell is nothing more than an exercise of constructing a language based on certain mathematical concepts, mainly abstract stuff like category theory.
As a result it as cryptic, hard to understand and useless in practice as those theoretical concepts (though the theoretical stuff might serve as basis for some other stuff that might be useful - not so with functional languages and especially Haskell)
I'll reccomend Erik Meijer's videos on introductory Haskell.
I haven't gotten though them all but I appreciate his style and depth of knowledge on the matter; he also points out many things that a Java or C# dev would naturally be curious about how to interpret Haskell.
Now, you may think that implies that you could do something like this to print a string one character at a time:
rsoat (x:xs) = show x (rsoat xs)
Buy you can't. If you try that Haskell complains "The function 'show' is applied to two arguments, but its type 'a0 -> String' has only one...."
Fair enough, one might reason - you're just passing max two things when it wants one so we can do something like this:
rsoat  = 
rsoat [x] = show x
rsoat (x:xs) = rsoat xs
But no, that just gets you the tail of your string because x:xs doesn't match x so it never prints the other bits.
What you may end up doing is something like this:
rsoat  = 
rsoat [x] = [x]
rsoat (x:xs) = show x ++ (rsoat xs)
But that's still not really doing what you wanted to do in the first place. It's sticking all your characters into a string and then reading that string all at once. And it's not a particularly obvious solution either if you don't know the language.
This may seem a silly example. But what happens when, as is frequently the case, someone wants to retrieve the nth element of a list? (list !! n) Haskell, as learnt through Learn You a Haskell, can easily be expected to drive someone up the wall who starts asking such questions - it's not a whole bunch of fun to play with.
To be honest, it does not seem you did a very good job of reading the book. If you're rooted in imperative languages, it takes some effort. I read the book when I had already had some basic functional programming experience, so my experience might not be so representative, but I've heard quite a few positive reviews from people for whom it was the first introduction to FP.
You seem to start off from a wrong premise that the show function prints things. It doesn't - it simply converts whatever value (of type a) you give it to a String (provided a is an instance of the Show typeclass). So seeing that you already have a string, a function which converts things to strings will probably not be very useful.
> rsoat  = 
> rsoat [x] = show x
> rsoat (x:xs) = rsoat xs
> But no, that just gets you the tail of your string because x:xs doesn't match x so it never prints the other bits.
Uh, no. It doesn't give you the tail of the string, it gives you a list containing just the last element of the argument (if the argument's not empty), or the empty list (if the argument is empty) - which you can read directly from your definition.
Furthermore, " x:xs doesn't match x" doesn't make a whole lot of sense - it's not supposed to match x, it's supposed to match a non-empty list. Which it does, and the first element of such a list gets bound to the parameter x - but you do not use the parameter in your right-hand side of the definition, so you effectively discard it.
Note that both pattern matching and the Show typeclass (and the corresponding function) are discussed in the book prior to the minimum example.
> You seem to start off from a wrong premise that the show function prints things.
No, I know what it does. That's how the book describes it however:
"The most commonly used function that operate on instances of this type class is show, _which prints the given value as a string_"
> Uh, no. It doesn't give you the tail of the string, it gives you a list containing just the last element of the argument (if the argument's not empty), or the empty list (if the argument is empty) - which you can read directly from your definition.
I continually forget that tail means the rest of the thing.
> Furthermore, " x:xs doesn't match x" doesn't make a whole lot of sense - it's not supposed to match x, it's supposed to match a non-empty list. Which it does, and the first element of such a list gets bound to the parameter x - but you do not use the parameter in your right-hand side of the definition, so you effectively discard it.
We're far enough away from what each other are thinking that this just isn't worth talking about as written.
You've already matched your list to x earlier in the program so x:xs doesn't get a chance to run. You're not showing x and then falling through to pass xs to the function again and chopping the first element off of that to show - and so on.
> Note that both pattern matching and the Show typeclass (and the corresponding function) are discussed in the book prior to the minimum example.
Fair enough, I don't have the printed version around. It's wrong on that point and I can see that it can be misleading. To their credit, here's the current formulation from the online version:
> Members of Show can be presented as strings. All types covered so far except for functions are a part of Show. The most used function that deals with the Show typeclass is show. It takes a value whose type is a member of Show and presents it to us as a string.
This is correct. Whether it qualifies as a proper discussion might be debatable, but since the particular typeclass is simple enough, and seeing that this appears very early in the book, it seems reasonable.
> You've already matched your list to x earlier in the program so x:xs doesn't get a chance to run. You're not showing x and then falling through to pass xs to the function again and chopping the first element off of that to show - and so on.
This is incorrect. Definitions are not really "executed" (or run) in Haskell; you simply replace the left-hand side of the definition with the right-hand side. You use the first definition (in file order) with a matching LHS. So in your example, the third definition for rsoat would be used for all lists with more than one element. So the "falling-through" as meant here is not what you get with, say, a switch statement in C.
>Now, you may think that implies that you could do something like this to print a string one character at a time:
I'm not sure how far you got after this point, but the problem is easily solved with a higher-order function:
mapM_ print "blahblahblah"
Or if you don't like each character being quoted:
mapM_ (putStrLn . return) "hello one at a time"
Or did you not want the characters on their own lines? In that case, you can do this:
mapM_ putChar "horse raddish"
But why bother doing that when you can simply do this?:
putStr "egg freckles"
>But what happens when, as is frequently the case, someone wants to retrieve the nth element of a list?
If you are frequently wanting to do this, you are probably doing something wrong. Haskell's lists are intended to be used as control structures, not indexed data structures. For those, you'll want an Array, Vector, IntMap etc.
I really liked LYAH, but it only starts out good. Once you hit Chapter 9. I/O. Prepare to fall off the rails. It only gets worse and worse and worse from that point onwards.
I don't think that's really the books fault as much as it is Haskells. I also think it's why you hear ALOT of people swearing Haskell is actually very easy, because everything up to chapter 9 is not very complicated at all.
I'm sure there are some very tallented people where this isn't true, but I get the impression that the people who are saying it's easy haven't gotten to the point where you can actually do things with Haskell, or developed a program with Haskell, or inter-operate with other libraries using Haskell, or tested their metal against the Parsing Combinators in Haskell (let alone making your own set), or ect. ect. ect.
It is a joke, but not an inside joke as much as a joke that would be understood by people from Balkan countries (Serbia, Croatia, Bosnia). Miran (the author of LYAH) is, judging from his first and last name, from this region.
In the local language (Serbian, Croatian and Bosnian are basically the dialects of the same common language), the most commonly used word for teach and learn is the same word, uciti, although there are separate words for these activities. Basically, whether you speak of teaching someone, or learning something is judged by the context.
Then, Learn you a haskell vs. teach you haskell is a wordplay in that sense.
A similar joke from the region: "Can you translate me to the other page of the street?"
The author is a very funny/insane guy. Exhibit A is his twitter account (https://twitter.com/bonus500). I wouldn't call it an inside joke, but rather a general feature of good comedy where it feels familiar yet distant.
It is a gamer|anime|comic book joke. There is a lot of cheaply written entertainment with poorly defined motivations ascribed to the heroes and villains. So what battle cry is used by an overly generic hero? Why an overly generic cry of "For great justice!" of course. Throw in a joke a about poor translations and you get their title.
I believe the title is a riff off of "Learn You Some Erlang for Great Good!" Some other books or online tutorials have taken that form of title. I don't really know why, though I suppose the silliness offsets the otherwise heavy nature of the content. (Learning Erlang is probably easier than learning Haskell for most people, but it can still be a mind stretcher if you've never done a functional language before.)