
Learn You a Haskell for Great Good - msvan
http://learnyouahaskell.com/chapters
======
tieTYT
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.

~~~
jordigh
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. :-)

~~~
digitalzombie
=/ I never got freebie stickers from No Starch Press (probably cause I buy it
through amazon). Their book quality is amazing, the paper and cover are very
nice quality (unlike other publishers >=( ), I bought the learn you some
erlang for great good, art of R programming, and the eloquent javascript.

------
rhizome31
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`?

~~~
adimitrov
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.

~~~
ccdan
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.

~~~
nbouscal
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.

~~~
ccdan
>>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.

~~~
nbouscal
You are simultaneously arguing that we should be using a natural language and
that the language of mathematics is too ambiguous. I think you have not looked
very closely at natural languages.

~~~
ccdan
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.

~~~
nbouscal
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.

~~~
ccdan
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

~~~
nbouscal
Honestly, I'm chalking this up to Poe's Law at this point. Take care.

~~~
ccdan
LOL... that's all you had to reply? Typical of FP advocates..

------
ikkyu
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?

~~~
nilkn
> I always see it mentioned on Reddit but I have yet to come across any
> notable project written with it.

xmonad, one of the best tiling window managers for Linux, is written in
Haskell (and is open source).

~~~
rhizome31
Not sure if it's notable, but I like hpodder, a command-line podcast client.
It happens to be written by one of the author of RWH.

------
misframer
Also useful:

Introduction to Haskell lecture slides - <http://shuklan.com/haskell/>

Real World Haskell - <http://book.realworldhaskell.org/>

------
gtani
I think there's a dozen or so free haskell books:

[http://www.reddit.com/r/haskell/comments/1af3iw/9_best_free_...](http://www.reddit.com/r/haskell/comments/1af3iw/9_best_free_haskell_books/)

[http://www.linuxlinks.com/article/20130316105209238/BestFree...](http://www.linuxlinks.com/article/20130316105209238/BestFreeHaskellBooks.html)

------
ilaksh
Anyone interested in functional programming might also be interested in
LiveScript <http://livescript.net/>

------
jamesbritt
Good book. Previous discussion on HN:

<https://news.ycombinator.com/item?id=535675>

<https://news.ycombinator.com/item?id=336085>

------
platz
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.

[http://channel9.msdn.com/Series/C9-Lectures-Erik-Meijer-
Func...](http://channel9.msdn.com/Series/C9-Lectures-Erik-Meijer-Functional-
Programming-Fundamentals/Lecture-Series-Erik-Meijer-Functional-Programming-
Fundamentals-Chapter-1)

------
6d0debc071
I didn't like LYaHfGG.

Take this in p52 for instance:

maximum' :: (Ord a) => [a] -> a

maximum' [] = error "Maximum of empty list!"

maximum' [x] = x

maximum' (x:xs) = max x (maximum xs)

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.

~~~
oggy
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.

~~~
6d0debc071
> 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.

This:

<http://i.imgur.com/7NKReoL.jpg>

is _not_ a discussion of the show type class and corresponding function.

~~~
oggy
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.

------
GhotiFish
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.

Chapters 1-8 aren't complicated in the slightest.

Chapter 9 is when it starts.

Haskell isn't easy.

------
dchuk
Is the name of this book some sort of inside joke or something?

~~~
dragandj
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?"

~~~
dasil003
Of course the strangest part of the title is the article "a" since "learn you"
is a valid if unusual idiom in English.

------
hawkw
I'm fairly certain I've seen this posted to HN before... good book, though!

