Hacker News new | past | comments | ask | show | jobs | submit login
How I Start: Haskell (howistart.org)
369 points by kungfooguru on Nov 17, 2014 | hide | past | favorite | 57 comments



For more practical examples like this, I highly recommend the Haskell Data Analysis Cookbook [1].

After learning the basics of Haskell, having a book chock full of practical examples of things like handling CVS files, JSON, trees, graphs, machine learning, and Haskell's outstanding support for parallel computation--is a really helpful resource. The code is extremely well written; clear, concise, and readable. The author has also put the source code on GitHub for each chapter. [2]

Afterwards, to take your skills to the next level, check out Simon Marlow's Parallel and Concurrent Programming in Haskell [3]. Simon now works at Facebook, where they're using Haskell in production [4] [5].

[1] http://www.amazon.com/Haskell-Analysis-Cookbook-Nishant-Shuk...

[2] https://github.com/BinRoot/Haskell-Data-Analysis-Cookbook

[3] http://www.amazon.com/Parallel-Concurrent-Programming-Haskel...

[4] https://code.facebook.com/posts/302060973291128/open-sourcin...

[5] http://community.haskell.org/~simonmar/papers/haxl-icfp14.pd...


Yes, I found the Data Analysis cookbook very helpful as well. However, it really drove home to me the need for a dataframe/Pandas-like library in Haskell... About half the code in every one of his examples was reading a CSV file, parsing it into some ad-hoc data structure etc. For very robust production apps, that can be justifiable, but for just a quick look at some data, it should just be a one-liner...


Carter is working on a numerical stack for Haskell that should make writing a pandas-esque library in Haskell pretty easy.

He can be found at https://twitter.com/cartazio and in the #numerical-haskell Freenode IRC channel.



of course that ignoring the fact that I kinda think people say "pandas" as a proxy for "i want a decent multi dimensional aggregation db thats a library for my language"... kinda thing. People say "data frame" but can mean a HUGE range of actual workloads


This rings very true to my use as well. I'd like to see something like Vinyl specialized to data frames, but nobody has built it yet.

Edit: see the post by coolsunglasses below—Carter's work is certainly the furthest along in this direction that I'm aware of.


And wrt syntx sugar for hlists and vinyl, there's some somestuff I hope to get into the merge window for ghc this week that might make that much nicer to work with. I hope.


Yay!


well,try out the hcons/hnil stuff in https://github.com/cartazio/HetList/blob/master/HetList.hs and give me feedback asap so I can somehow wing getting it under consideration later this week. merge window for big stuff is FRIDAY


Awesome article! You really cover a lot, in a short but easily digestable write-up! It might be a little fast for complete beginners though :/...

I've come to be quite happy with my current VIM setup. I'm using,

* haskellmode for _t and _T (show and insert types, respectively) [0]

* ghc-mod for integration with neco-ghc and syntastic and for running ghc check [1]

* neco-ghc [2]

* neocomplete that uses neco-ghc, for completion suggestions [3]

* syntastic for hlint checking on save [4]

[0] https://github.com/lukerandall/haskellmode-vim

[1] https://github.com/eagletmt/ghcmod-vim

[2] https://github.com/eagletmt/neco-ghc

[3] https://github.com/Shougo/neocomplete.vim

[4] https://github.com/scrooloose/syntastic/


Nicely done. I find that the most useful pedagogic tool for learning are extensively annotated non-trivial examples (with emphasis on extensively annotated).


What do you think about the lens library?

I have been trying Haskell for a few weeks and this library feels strange. Also I don't really think I need the things it provides. But perhaps I just don't understand it.


Lens is difficult to get your head around. It is simultaneously a rather simple idea ("bundle getters and setters together... ") and a ridiculously sophisticated and generalized implementation ("... in every conceivable lawful way such that they all work together as they ought to!").

You probably do want lenses. Learning to use them is its own "mind blowing" experience similar to learning functional programming itself. Better, they integrate smoothly with Haskell so once you've learned them the cost of using them is quite small.

Unfortunately, learning lenses from `lens` itself is quite hard. There is some amount of training materials (shameless plug here)

    https://www.fpcomplete.com/user/tel/a-little-lens-starter-tutorial
    https://www.fpcomplete.com/user/tel/lens-aeson-traversals-prisms
but the library itself is typically targeting a proficient user far better than a new one. I'd recommend trying to implement your own lenses as a learning task. If you don't bother generalizing it as far as Ed has then the core concept is very simple. I wrote up a CodeWars task for this using the Van Laarhoven style used in `lens`, but there are even simpler forms as well.

    http://www.codewars.com/kata/54258ffb430ca2e4b5000239


There's also simpler packages, right? Targeted at having less power, but being more understandable as a result.

Was lens-family one of the simpler ones?

    https://hackage.haskell.org/package/lens-family


There are a lot of lens packages. I'd roughly split them into the "Van Laarhoven style" and the "Abstract style".

In the Abstract Style there is `data-lens` and `fclabels`. These use some kind of packaged form of (getter,setter) and require a Category instance to compose using (.). They are all mutually incompatible with one another.

In the Van Laarhoven Style are `lens`, `lens-family`, and `lens-family-core` of which the last is the simplest. These are all mutually compatible, and compose automatically using regular function composition and the Prelude version of (.), but they're somewhat hairy to see at first since they must expose their underlying type (for subtyping purposes) and that one is pretty unexpectedly weird.

I recommend using Van Laarhoven style lenses. If you really want an abstract style lens, fclabels is the best I've been told.


Thank you.


You can think of a lens as just a pointer (like in C). They're not exactly like a pointer...you can't get or modify the address that it points to. But you can get and modify the thing that it points to, which is primarily how you use pointers in C.

But lenses can do things that pointers can't do. Namely, they can be composed. If you have a lens that points to a person's birth date

    dob :: Lens Person Date
...and a lens that points to a date's year field:

    year :: Lens Date Int
Then you can compose them like this:

    (dob . year) :: Lens Person Int
Normally it would be easy to retrieve the person's birth year with plain function composition. Lenses let you do that too. But setting the person's birth year is much more painful. This is where lenses shine.

    set (dob . year) 2004 person


Huh? In C, if you have a function from Person* to Date* and another function from Date* to Int*, you can compose them as well, and then use the resulting function to both get and set a person's birth year. The syntax is admittedly ugly, but I don't see any asymmetry between get and set.


Yes, I was talking about plain pointers (i.e. Person*), not functions of pointers.

Sure, you can do both get and set, but the simple syntax is precisely what we're going for here. Without lenses that set line would have looked like this:

    person { dob = (dob person) { year = 2004 } }
And this is just one level of nesting. Adding more levels gets really ugly. Also, lenses make it easy to do this kind of thing in a dynamic and generalized way.


"Functions of pointers" do seem an in-place equivalent for simple lenses. Pointers themselves less so - you can't compose pointers, and they take zero (when getting) or one (when setting) argument whereas a lens takes one or two.

Much like traditional getters and setters, lenses can offer more functionality though - for instance, an angle can be got and set in radians or degrees.


Yeah, that's interesting. I chose pointers because I was looking for a simple metaphor that imperative programmers would understand easily. If you ask random C programmer how to pass a single thing to a function such that you can both get and set it, pointers are the first thing that most of them will think of.


Pointers being symmetric was the point of his analogy. The asymmetry shows up when the setter is pure, returning a new version of the record instead of mutating it (as is the case in Haskell).

A getter is simple:

    x = s.foo.bar;
As is an impure setter:

    s.foo.bar = y;
But a non-mutating setter is a bit more work:

    Foo foo2 = s.foo;
    foo2.bar = y;
    S s2 = s;
    s2.foo = foo2;


It's a pretty advanced library, and I don't think you should use it if you've only been trying Haskell for a few weeks. I've been using Haskell for about 7 years, 5 of which commerically, and I've never used it seriously. I find the smaller lens libraries, like 'fclabels', solve the most important problems 'lens' also solves, but with a lot less surface area and complexity. But even that can wait until you're further along.


For me it greatly simplifies my data access code. Sometimes I'll have multiple-layer nested data objects, and it's just not reasonable to access that any other way.

It's useful, but the amount of magic in it can be off-putting. For average developers it's a tradeoff of magic for functionality. Debugging it can be a nightmare if you use too much of the magic, but using it for simple data access and setting can be pretty straightforward.


Lens is fantastic when you're doing a lot of work with deeply nested data. Often times, you shouldn't be doing that in the first place.


I found this talk by edward kmett incredibly helpful[0]. I kept rewatching parts of it bit by bit until I managed to absorb it all (there is a lot of information for a beginner) but I found it hugely helpful and mind-blowingly powerful.

[0] https://www.youtube.com/watch?v=cefnmjtAolY


Lens has some very advanced abstractions, which can lead to some very thorny error messages. I second the suggestion to stay away from it for now.


Great article! As a programmer yet to have tried Haskell, this was actually one of the first articles I've read about Haskell which made sense to me. I tend to have a lot easier to learn from practical examples than the more academic approach normally seen in Haskell learning material and blog posts.


This is a common pedagogical problem with Haskell. We Haskell programmers are tempted to jump right into monads and functors and stuff, but the reality is that these (really very simple) concepts can't easily be taught by analogy. Often times the best way to learn is to slog through some examples.


Great write up, nice dissection of a simple (but not hello world simple) app, with all the ecosystem setup, etc. Apparently he is writing a book now - looking forward to that.

I think it is very hard to understand what a "beginner" needs - I now come across tutorials that finally make a certain concept "click", however the reason might not be that that specific tutorial was great, but rather that I have already hit my head on a bunch of other tutorials and practice that "prepared me"... Howver, Chris Allen actually working on teaching Haskell to a bunch of beginners is probably a great way of understanding what helps people to 'get it' sooner.


When it comes to learning something like Haskell you are caught in dilemma between two ideas - Should you learn a functional programming language for fun and because it will make you a better thinker? or should you use your existing tools / stack to build something better than you have done before. What will be the better utilization of time?

While I was more oriented to former in the past, I have been inclining to latter, lately, for the reason, that what you have built remains more obvious to show and be proud of rather than knowledge of a programming language which might not be practical to build something good for variety of reasons (not soon to say the least).


I have been learning a bit of Haskell on the side recently just for the thrill of learning something completely different to the way I'm used to writing code.

My two cents so far is that using Haskell for "Real World" applications is not practical (at least in my experience), but by writing small applications in Haskell you learn a lot, it changes how you think. In my opinion, learning Haskell makes you a better programmer.


I have a crawler downloading 160 million websites a day, almost all in Haskell. It is a much more practical language than the alternatives.


>In my opinion, learning Haskell makes you a better programmer.

No, it makes you a more dissatisfied programmer.

Dissatisfied with how poor the tools in other ecosystems are.

You can't take Haskell with you. Erik Meijer is wrong about this. You can't use monads productively in Python. You can try, but it doesn't work well.

You need Haskell. Laziness, FP, immutability, types, the whole shebang. It all hangs together in a well designed way. Not even Scala can do FP well.

https://twitter.com/bitemyapp/status/534498324296921088

https://twitter.com/bitemyapp/status/534498480430284801

https://twitter.com/bitemyapp/status/534498423870066688

https://twitter.com/bitemyapp/status/534498512398864384

https://twitter.com/bitemyapp/status/534500037901176832

To quote mwotton:

"here is a lightsaber, an elegant and powerful weapon. After you practice with this, you will be much better at stick-poking." is absurd.

More powerful abstractions tend to invalidate more and more combinations of terms. This means the space in which your program will be correct gets narrower and narrower.

The good news is, it means your abstractions will more precisely represent the correct program you want.

The bad news is, you'll want help from the computer and a well-designed language.

I have a video of my Haskell workflow here: https://www.youtube.com/watch?v=Li6oaO8x2VY

It's worth considering in this context what Haskellers mean when they talk about "type tetris".


> No, it makes you a more dissatisfied programmer.

Maybe it makes you a more dissatistfied programmer.

> You can't take Haskell with you. Erik Meijer is wrong about this. You can't use monads productively in Python. You can try, but it doesn't work well.

Can you explain why? Because its my experience that monads, once you understand them even a little bit, open up a way of thinking about and addressing problems that can be productively used in most programming languages (Python certainly included).

> You need Haskell. Laziness, FP, immutability, types, the whole shebang. It all hangs together in a well designed way.

Certainly Haskell's very nice and hangs together fairly well (though its also got some warts.) And certainly, some people will be much more productive with Haskell than with other languages. But that doesn't mean that learning Haskell won't improve your productivity with other languages, and that the combination of available existing libraries, etc., might still make some other language a net win for a particular real-world project.

> Not even Scala can do FP well.

Scala is certainly less good at some things than Haskell is -- and its especially unsurprising that its not as great at FP since it deliberately compromises Haskell-style FP to support extended Java-style OO (and thereby also to interop well with Java.)

> "here is a lightsaber, an elegant and powerful weapon. After you practice with this, you will be much better at stick-poking." is absurd.

Except its not, either in the literal sense (lightsaber fighting, after all, is stick poking with SFX) or the figurative sense.


> Can you explain why? Because its my experience that monads, once you understand them even a little bit, open up a way of thinking about and addressing problems that can be productively used in most programming languages (Python certainly included).

I talked about part of the answer to this question at the New York Haskell Meetup awhile back.

http://vimeo.com/59215336


The criticism there doesn't seem to be about why static typing is particularly a bar to productive use of monads, just the general criticism that dynamic languages lack type safety, and so limit you to monadic operations without the safety of static languages. It also makes the mistake of asserting that, because dynamic languages lack enforced types, the definition of a monad is different in those languages is different. But the definition of a monad is the same -- and includes the Monad Laws as well as the signatures of the bind and return (or fmap and join) functions -- independent of language. And the monad laws -- which even Haskell can't enforce for user-defined monads -- are just as important to correct monad use as the type signatures of the bind/return functions. Enforcement of essential properties is useful, but its not essential to productive use as the use of Monads in Haskell itself demonstrates.

Its manifestly clear that productive programming without type safety is possible, and I don't see anything there that distinguishes why that would be less true with monads.


> Dissatisfied with how poor the tools in other ecosystems are.

Don't pretend that the Haskell tool ecosystem is better than the others.

Does Haskell have a debugger which is as good and easy to use as the Chrome Developer Tools (JavaScript) or Visual Studio (C/C++/C#)? Is there a good editor (comparable to VS for C# or Eclipse/NetBeans for Java) with type-aware code completion? And don't tell me about cabal, that tool is much worse than package managers in other languages, the amount of time people waste with cabal is unbelievable.


Of course not.

(I'm also starting to believe that these "Haskell is the best thing ever"-kids will become a bigger issue than all those "Haskell is not practical"-naysayers for the growth and success of Haskell.

The latter is annoying, but can cause people to sit down and think how working with Haskell can be made more straight-forward, while the former is blinded by his ideology and is hostile against improvements which could be seen as acknowledgements of existing flaws in the language/ecosystem.)


Haskell isn't the best at everything, but it is practical and that's my point.

Asserting that something is practical based on...well...practical experience is not ideology. It's damn near the opposite.


Erik Meijer never said you should use monads in Python. Erik Meijer says "think like a fundamentalist, code like a hacker".


What "Real World" applications do you think Haskell isn't practical for? For instance, why wouldn't Haskell be practical for web development?


Nice article.

As of lately, I've been using a bundled GHC app for OSX development. Makes it quite easy to keep (and switch between) multiple Haskell environments.

http://ghcformacosx.github.io/


Not sure if you caught this, but that's what Chris Allen is linking to on this page http://new-www.haskell.org/downloads/osx

Also, that app is great. Really nice that it comes with Cabal 1.20 .


Oh.

IIRC, haskell.org used to point to a download of the Haskell Platform for OSX (definitely not to ghc.app at any rate), so when I saw that's where it pointed, I didn't even notice that they'd changed it.


The link for OSX points to `new-www`.haskell.org. I'm sure the old site still links to haskell platform.


For me, the lectures from Nishant Shukla were really helpful: http://shuklan.com/haskell/


This is a great, well-written article. I'm going to try it out later tonight. Hopefully going through a real-life example will make LYAH a little less cryptic.


I like the How I Start serie.On the other hand,while I get that languages have their specificities,I'd like the same project to be implemented in all these languages,to be able to get a quick understanding about how working with these languages feels like.

You know like a TodoMVC ,but in form of tutorial around the same project,a webapp for instance,which would require as little library as possible.


I'm the auhtor of the Erlang article on How I Start. I've felt the same in some ways because it would offer a nice comparison point, but the problem with this idea is that it doesn't let the authors pick a problem for which they think their tool shines.

In a way, forcing the same problem on all authors is more or less risking telling them "you may have to use the wrong tool for this job, but please tell us how you'd do it."

Instead, I think the current format is, well first of all nicer for the author (they can pick what inspires them), and also gives you a richer level of content where you may end up learning more than you thought you would.

For example, the Erlang text focuses on Releases and shipping Erlang systems, something I felt was still blurry in a lot of people's minds. the Elixir project is done with a concurrent approach that wouldn't necessarily carry over the same way in Ruby, and Ruby's text is showing how to build a gem.

Letting the authors pick their subject means they can choose to focus as much as possible on what they feel is trickier with their tool of choice, rather than just showing a given program, for which a site like rosettacode.org might be more interesting.


Odd, I think I disagree with you because of the convenience to the author. Especially in regards to how things extend to other problems. Or any costs in building a solution.


You might like this post and repo on the iterated prisoner's dilemma then: http://jacquesfuentes.com/essays/2014/10/31/Iterated-Prisone...


This is a good series. Very few tutorial mention the dev environment setup.

It would be great if this can be complemented with a list of projects along with the unit/integration test cases (only description) that the end-system should pass along with a cloud deployment specification. There could be advanced section that encourages discovering edge cases.

When one wants to practice they can slowly climb the ladder to understand how to implement a system and gain expertise. I always find myself lacking in ideas on how to practice what I know. Practising the same set of data structures and algorithms is not very motivating.


Very interesting! Is there something like this for other languages / frameworks? I'd love to see something like this for Ruby + Sintara + MySQL/PostgerSQL for writing a RESTful API setup.


Sorry if this isn't what you're asking, but this article is part of a series for different languages: http://howistart.org/


Hi, author here!

It's intentionally tiny, so a bit trivial, but here's a URL shortener in Scotty. Scotty is a library that gives you a toolkit for making webapps in a manner similar to Sinatra.

http://bitemyapp.com/posts/2014-08-22-url-shortener-in-haske...


This is a really great idea and series. Looking forward to more.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: