Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jsoo1/2b5adf49bf626a202bda188fa3661eff to your computer and use it in GitHub Desktop.
Save jsoo1/2b5adf49bf626a202bda188fa3661eff to your computer and use it in GitHub Desktop.
Hillel Wayne's "The Hard Part of Learning a Language" answered by me for Haskell

Hillel Wayne’s - The Hard Part of Learning a Language as answered for Haskell by me

First of all, thank you for giving Haskell a try! Welcome to a lifelong pursuit of Learning Haskell.

Note that this is colored by my experience. I do not use Windows. I do not use {,neo}vim.

I want to answer this survey to prevent another Tech Thoughtleader from misrepresenting Haskell. Haskell is hard and different enough to warrant this disclaimer:

Haskell is a pragmatic and effective language for standard tasks. BUT it is best to learn Haskell first, then apply it to your problem.

Please do not learn Haskell to accomplish a task you would normally do in $USUAL_LANGUAGE unless you are some kind of functional programming person already.

Even if you are some kind of functional programming person, have you worked with System F(omega)? Laziness? First class effects? If not, do take some time to get acquainted.

There are many Haskell tooling/language posts. I would consider them longer-form and more edited versions of this very survey. These two are my favorites:

How do I install it? The docs say brew install, but I’m on Windows.

Thankfully, Windows is almost a first-class platform for Haskell. Simon Peyton Jones (arguably the primary shepherd of the standard haskell implementation - GHC) was a Microsoft Research employee and worked for many many years on Windows.

ghcup works quite well for installation, I hear, but does want WSL2.

Please refer to http://dev.stephendiehl.com/hask/ for more specific notes. I believe that to be the long-form version of what you want for this question.

  • Do I have to use WSL?
    • No, but you might want to (see note about ghcup)
  • Why is it breaking on WSL?
    • No idea

How am I supposed to be writing this? Do I download an IDE? Is there a Vim plugin? Is this ostensibly editor-agnostic but really supposed to use Emacs?

Editor agnostic. {,neo}vim support is quite good and used by a lot of Haskellers. Emacs support is also quite good. But! If anything, Emacs is secondary to vscode/{,neo}vim for Haskell work.

The commonality between most Haskell work is the compiler, GHC.

  • Uh oh, there’s two competing plugins. The communities hate each other. Which do I choose?
    • I don’t use {,neo}vim, but I think the builtin language server bits along with haskell-language-server should work (Also, syntax highlighting is builtin to {,neo}vim, so no competing plugin problem)
    • haskell-language-server is quite new, though. If you have trouble, get ghcid and run it in a split terminal. If that fails, use ghci in a split terminal

How do I read from a file? How do I parse JSON? How do I pull environment variables?

I am not going to suggest you need a Phd to write Haskell, but even these questions smell like “help me do X in Y” where Y is Haskell.

As per the first disclaimer: please try to accept Haskell on its own terms before writing $THING first.

  • How do I do any of the things that aren’t part of the core syntax/semantics but are super common problems people face every day?
    • JSON - The Aeson library is the industry standard: https://hackage.haskell.org/package/aeson
    • Environment Variables - In “base” (the stdlib that comes in the box with GHC). Specifically environment variables live in in the System.Environment{,.Blank} modules, depending on base version with many other packages providing different takes.
    • Reading from a file - readFile is the easiest function. It is also in base (in System.IO)
  • I’m going to have to memorize another 100 functions and their parameters, aren’t I?
    • In some ways yes. But! the type system does a lot of the memorization for you.

What are the language quirks that will cost me an hour to discover?

Not to say that Haskell as implemented in GHC doesn’t have quirks, but please don’t mistake fundamental differences with $USUAL_LANGUAGE with quirks. Hopefully you understand that Haskell is a functional language based on the lambda calculus rather than the Turing machine.

  • What are the footguns that will cost me a day to debug?
    • String. The stdlib String type is a list of Char (which I think are utf-16).
      • Because of this, there are two common types of String data with more compact representations: Text and ByteString.
      • Text is a unicode/utf-8 encoding of strings, whereas ByteStrings are just that (a string of bytes).
      • Moreover, each of Text and ByteString have lazy and strict variants.
      • In general this is actually a good thing but can be very tricky when first encountering them in application development.
      • If you want to use Text or ByteString literals, use the OverloadedStrings language pragma at the top of your file like so:
        {-# LANGUAGE OverloadedStrings #-}
                    
      • There are also standard conversions between the various types, for which I recommend this stackoverflow answer: https://stackoverflow.com/a/40491001
  • What are the things that are just different enough from what I’m used to that will confuse me? What will trip me up every time I switch back to a different language?
    • As mentioned previously, Haskell has a fundamentally different semantics than your standard imperative language. In particular, getting the computer to “just do stuff” is approached with caution and principle.
    • If all goes well, you will take this pedantry back over $USUAL_LANGUAGE
  • What parts of the core language should I avoid at all costs?
    • There are not many but some functions in base might crash by historical accident. However, you should be able to spot them by their type signatures (i.e. head).
  • What are the snippets that look right but are secretly wrong?
    • There are precious few of these. Haskellers are proud of making correct-by-construction programs.

How is the help organized? Is there an official site? How’s the site laid out?

There are two major resources:

  1. hackage documentation - the official documentation for most any package, including base. (https://hackage.haskell.org) Segmented by package (installable unit comprised of haskell modules).
  2. hoogle - type directed search leading back to hackage (https://hoogle.haskell.org)
  • Is it actually useful or will it make me want to smash all computers?
    • hoogle search is great. I generally love Haskell documentation, despite a few funny outliers.
  • Does it have documentation for people besides “complete newbies” and “language maintainers”?
    • There is a growing number of blog posts and resources for the mid-level Haskeller. Historically, you may have been harder pressed for mid-level documentation.
  • Can I download the official docs, or will I have to be online to read any of the references?
    • You can download official docs, they come with the package as installed by cabal (the build tool, see the longer form resources above for detailed explanation).
  • Are there official docs?
    • Yes, see hackage.
  • Oh wait, I’m supposed to learn from $BOOK, which is only available in physical form.
    • There have been some attempts but there is no royal road to Haskell. I usually find people learn it by trying once with one resource, and again with another. There really is no best path, yet.
  • And people keep telling me that $AUTHOR is a serial killer?
    • There are precious few instances of this in the Haskell community. Though Haskell from First Principles ought to be avoided for an (admittedly less aggregious) issue of personal integrity.

I hit problem X. Should I look for help in the official docs, or the FAQ, or the community, or should I be putting random stuff into Google?

A web search is not a bad resource, tbh. Haskell has changed a lot over the last ten years. As a rule of thumb, I suggest looking for a second opinion when the GHC version from the answer is <=7.

  • Oh, looks like someone answered this in 2007! Which was eight versions ago. Are they still right or is their advice obsolete?
    • There are likely better answers, but for some reason Haskellers are very studious about updating their stackoverflow answers.
  • I found something from 2011 that said the 2007 person was wrong. Do I do what 2011 dude says or should I assume his advice is also obsolete?
    • See above. 2011 was still ghc@7.X

How do I debug? Will doing anything other than “break into repl” be like pulling teeth?

Yes. GHCi has lovely debugging capabilities but does not provide what you probably think of when you think of “a debugger”.

In general, Haskell programs are less amenable to debugging as is common in $USUAL_LANGUAGE. This is because of the immutability of the language and emphasis on correctness-by-construction.

  • Will “break into repl” be like pulling teeth?
    • GHCi is a world-class REPL. Though it should be noted there are some sick (maybe even essential) lifehacks when it comes to customization. (See the long-form blogs above).
  • Is this one of those communities which think debuggers are for n00bs and you should write a lot of print statements?
    • Maybe. As stated above, Haskell programs require less debugging in the usual sense.
    • Do be advised of the functions in Debug.Trace when println debugging is required.

Testing. Is unit testing part of the core library, or do I need to install a third party framework?

  • Or both? Like how Python comes with unittest, but everybody uses pytest.
    • No testing library is provided with base
    • Testing is also less required than in $USUAL_LANGUAGE. For reference, see the entire history of the tests vs types discourse.
    • A common library for testing is an rspec-like one called HUnit. I recommend it, though there are others that are not so BDD oriented (see: tasty). I can’t speak against any, they are usually quite good.
  • Or how Ruby has Minitest, rspec, and Test::Unit, and people get into fights about which is best.
    • Apparently I’m supposed to learn Cucumber?
      • In general, tests are encouraged in moderation in Haskell. There are no huge fights because people are more concerned with fancy types.
  • What about property-based testing? Does $LANGUAGE even have a PBT library?
    • It has the granddaddy of them all called QuickCheck. There are newer ones like hedgehog. They are, of course, world class.
  • How does the test runner work? How long should I try to integrate it with my dev environment before giving up and running it in a separate terminal?
    • See the long-form posts above. Usually it is run with a build tool like cabal or stack and a test subcommand.

How do I build? How do I package? How do I manage my environment?

There is a bit of competition between two main build tools, stack and cabal (there is also nix, but don’t be encouraged to use it at first unless you already know nix).

In general, it is as simple as

stack build

or

cabal build

(I prefer cabal)

  • What are all the command flags I should be using that aren’t default for various reasons?
    • There are specific GHC options to make non-exhaustive pattern matching and uninitialized record fields errors instead of warnings. These should always be turned on, among a couple others. I mention this because there are a dizzying number of ghc options to wade through and those two are the biggest. For reference, those are:
      • -Werror=incomplete-record-updates
      • -Werror=incomplete-uni-patterns
      • -Werror=missing-fields
      • -Werror=partial-fields
    • Another good one is -Wall. -Wall, ironically, does not warn for all the flags. For that you need -Weverything, but it is annoying (and unnecessary) for the n00b.
  • How am I supposed to “properly” organize my project files?
    • See the Stephen Dhiel long-form post for a much better explanation than I can say here. Though do be aware that cabal, at least, is quite flexible if you have something in mind that is not idiomatic.
  • I organized everything properly, how come it’s still not finding my module?
    • When using cabal: you need to expose the module in the exposed-modules field of your library.

Package management.

  • How do I find the packages I need? If there are multiple competing packages, how do I decide which one I should use?
    • Hackage is the official source.
    • Often reddit is used as a means of announcing packages.
    • You will find a lot of packages that do the same thing. Most are of quite high quality.
    • Deciding is one of the fun parts of Haskell. At some point, you will be able to make the decision yourself.
  • And now I have to learn the APIs of the third-party packages.
    • Yes. But again, the type system makes the APIs very clear usually.
  • And the API of the package manager itself.
    • Yes, this is less nice, but please refer to the long-form posts above.
  • What are the “canonical” packages the community has consensus on? Am I going to have to dive into the community to find out what I need to install? I do? Oh great.
    • This is too big a question to really answer here. I would probably turn to reddit or some other forum to get more details. If you have gotten really dialed in, reading the hackage page can give you a good sense.

So… the language community.

  • Where are they? Will I have to join Yet Another Slack? Install Yet Another Messaging App? Do I have to set up a dedicated machine just to keep connected to an IRC channel?
    • IRC is pretty good.
    • I don’t use reddit but I think reddit /r/haskell is quite good
    • Twitter is also good.
    • Once there was a slack, but it is also To Be Avoided.
  • Are they friendly to beginners, hostile, passive-aggressive?
    • Quite friendly!
  • Are there any missing stairs or known abusers?
    • Abusers are thankfully few and efforts have been made to oust them
    • Surely there must be some of each, but the examples are thankfully rare
  • Are there high-profile rivalries?
    • stack vs cabal is the big one, but it is a friendly competition more than anything.
  • What innocuous-seeming topics always turn into a flamewar? Is my question even safe to ask?
    • Haskellers try to be understanding when the question is asked in good faith
    • There may be some third-rails but I am not aware of them
  • Now they’re explaining something way above my head. Is this necessary to get, or are they just cursed with knowledge?
    • A lot of the joy of Haskell is that the ceiling is very high
    • Do not feel bad if you don’t get the category theory or what-have-you
    • Advanced topics are surprisingly relevant and useful in Haskell, but are usually not required
    • Please, though. Do not dismiss things because you don’t get them yet
    • Another one of the joys of Haskell is that it is a place to apply math and abstraction to computation. I understand if you Just Want to Write Your App, but I love how un-anti-intellectual the Haskell community is. Please let us have our advanced topics, we are not really interested in being the next $USUAL_LANGUAGE.
  • What opinions do they have on other programming languages? Are they going to look down on me for writing a lot of Python?
    • There is a great overlap of people that came to Haskell from Python.
    • You will definitely encounter frustration with the hegemony of imperative programming. Particularly because Haskell has Just Solved a lot of difficulty with imperative programming. I am of the opinion that Haskell really is the finest imperative language.
    • As long as you are not going to defend $USUAL_LANGUAGE on ideological grounds, and are willing to look at Haskell in good faith you should be fine. By and large, Haskellers tend to be quite big on honest argumentation.
  • Do they think I’m subhuman scum for using Windows?
    • The Simons tended to GHC from Microsoft Research for decades. It was good enough for them.
  • What are all these in-jokes supposed to be?
    • “A monoid in the category of endofunctors” is frustratingly the most accurate definition
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment