[Haskell-cafe] What is your favourite Haskell "aha" moment?

Simon Peyton Jones simonpj at microsoft.com
Wed Jul 11 16:24:51 UTC 2018


Also, languages are borrowing from each other at a rapid rate these days (eg Rust traits are equivalent to type classes) so it's hard to find a "killer feature" in Haskell any more

That’s true, and to be celebrated!

One thing that stands our for me is the ability to abstract over type constructors:
            f :: forall (m :: * -> *) (a :: *). Monad m => a -> m a

That ability is what has given rise to a stunningly huge collection of abstractions: not just Monad, but Functor, Applicative, Traversable, Foldable, etc etc etc.   Really a lot.  It opens up a new way to think about the world.  But only made possible by that one feature.   (Plus type classes of course.)

Do any statically typed languages other than Haskell and Scala do this?

Simon

From: Haskell-Cafe <haskell-cafe-bounces at haskell.org> On Behalf Of Neil Mayhew
Sent: 11 July 2018 17:12
To: Haskell Cafe <haskell-cafe at haskell.org>
Subject: Re: [Haskell-cafe] What is your favourite Haskell "aha" moment?

I came to Haskell from C++, and I was used to the idea of parametric types and functions from C++ templates.

However, what I really liked about Haskell's way of doing these was that, due to type inference, not only is there a lot less ceremony involved, but code is generic (parametric) *by default*, and thus much more reusable, although you still have the option of tightening it up by adding a type annotation (eg for performance reasons). For a while, I was writing all my C++ code as templates, but this ended up being a pain.

Also, traditionally C++ has not allowed you to place any constraints on template arguments (type parameters) whereas Haskell's type classes are a very elegant way of doing it. (C++ now has concepts, but I haven't taken the time yet to see how they compare with type classes.)

I was also used to function overloading, which is somewhat similar to type inference, in that the compiler will pick an implementation based on the types of a function's arguments. This is similar to Haskell picking an implementation from among type class instances. However, what blew me away is that Haskell can overload based on *return type* as well as argument types. I haven't seen any other production-ready language that can do this. A great example of how this is useful is the regex library, where you can select from among widely varying styles of regex matching result simply by type inference, ie without needing any type annotation.

There were a *lot* of other things I found amazing, but others have covered many of these already. Also, languages are borrowing from each other at a rapid rate these days (eg Rust traits are equivalent to type classes) so it's hard to find a "killer feature" in Haskell any more (except laziness, perhaps). I think it's more the well-balanced combination of all the features that makes Haskell so pleasant to work in, and it's hard to demonstrate all of these in a single example.

My own favourite "gem" is this code for computing all primes, based on code in a paper[1] by Doug McIlroy:

primes = sieve [2..] where sieve (p : ns) = p : sieve [n | n <- ns, n `mod` p /= 0]

I think care must be exercised, when using examples like this one, to avoid giving the impression that Haskell is a "toy" language. However, what I find interesting about this example is that all other sieve implementations I've seen work on a fixed size of sieve up front, and if you later change your mind about how many primes you want, eg because you're expanding a hash table and want a bigger prime for the size, you typically have to start the sieve from scratch again.

[1]: http://www.cs.dartmouth.edu/~doug/sieve/sieve.pdf<https://na01.safelinks.protection.outlook.com/?url=http:%2F%2Fwww.cs.dartmouth.edu%2F~doug%2Fsieve%2Fsieve.pdf&data=02%7C01%7Csimonpj%40microsoft.com%7Cce59cb95fe304d442b8d08d5e7490739%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636669223196857658&sdata=1UGE8hoL8B9yMjXqJbe5HV%2FsAXlpoB653kePOrgpCNY%3D&reserved=0>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20180711/3ab5fd84/attachment.html>


More information about the Haskell-Cafe mailing list