OK: I lied. One more problem -
Haskell forums are famous for " I’m completely with you. I have the same experience with the Haskell subreddit, r/haskell
. I can’t understand most posts - they’re meaningless to me. Yet I’ve been writing apps with Haskell for years."
No, you shouldn’t stop making posts like that - but you should keep them in their own threads and try to promote discussions about eg useful libraries too. Letting them leak into a thread like this - no! Keep them away from threads for newbies too. Try to look like Haskell is an accessible language with an accessible community.
This is how I would suggest selling Haskell - it would be page one of a Haskell By Example:
Haskell is a strange, strange language. Just not quite in the way the memes say - it’s not as hard to learn as the memes make out (although it is a language that best suits dedicated programmers) and IO is actually easy. It’s strange because it maxes out expressivity - the stuff that programmers love - and safety at the same time. If it was a food then it would be a bacon covered cheeseburger or chocolate sundae… That was actually good for you.
Obviously, that’s a big claim. Can we prove it? Just watch…
Here’s a function that adds two numbers -
add a b = a + b
add 1 2 => 3
Now watch me turn it into a function that adds 42 to any number it gets
f42 = add 42
f42 8 => 50
Slightly interesting, but not very (that’s called Currying btw - ie you give a function some of its arguments but not all of them and get a new function that has stored those arguments - they are now pre-set.) Here’s a better one:
quadratic a b c x = (axx) + (b*x) + c
quadratic 4 2 1 9 => whatever
f = quadratic 4 2 1
f 9 = same whatever
You can make more than one curried function from the same base function:
g = quadratic 11 2 7
And you can do this
f map [1..10] => lots of results
g map [1..10] => lots of results
And even though we haven’t defined any type signatures for the above, Haskell has still deduced them. So the following is a compile time error:
f “cat”
But, as they say, wait - there’s more! This is how easy it is to define a “class” that does maths for fractions (this time I am writing type signatures for extra control):
data Frac = Frac {num::Int, denom::Int} deriving Show
frac::Int->Int->Frac
frac num’ denom’ = Frac{num= div num’ gCD, denom= div denom’ gCD}
where gCD = greatestCommonDenominator num’ denom’
fracAdd::Frac->Frac->Frac
fracAdd a b = frac num’ denom’
where denom’ = (denom a) * (denom b)
num’ = (num a) * (denom b) + (num b) * (denom a)
fracSub::Frac->Frac->Frac
fracSub a b = fracAdd a (fracNeg b)
fracNeg::Frac->Frac
fracNeg a = frac (-1 * (num a)) (denom a)
fracMul::Frac->Frac->Frac
fracMul a b = frac num’ denom’
where denom’ = (denom a) * (denom b)
num’ = (num a) * (num b)
Here’s an example
frac 1 4 * frac 2 3 => frac 1 6
…Ie 1/4 * 2/3 is 1/6
And the cool thing is I can now code, without any more fuss, this -
f (frac 1 4 * frac 2 3) * g (frac 1 2) => whatever
Yes, it’s that insanely simple. You get all the refactoring and debugging advantages of strong type checking and generics without crazy verbosity. And not only that but Haskell can be compiled and run at Java speeds but can be used at a REPL.
Interested?
That was the demo: read on if you want a fast tutorial followed by suggestions for books and more online resources.
Contents:
Demo
How to use GHCI (one hundred words or less)
Functions
Lists, strings, and tuples
IO
Data structures
Maybe and >>=
Modules
Some useful libraries
More resources