So, thread below 👇
- focus on immutability and separation of side-effects,
- higher-order functions,
- data types with support for sums/choices.
Everything but the last point is available in many mainstreams languages *now*.
In my experience, "length applies to any list, whatever the type of the contents" (in other words, length :: [a] -> Int) seems intuitive to most people.
- is black magic when using IO,
- chains validations when used with optionals,
- gives several results back when used with lists,
- threads a value with used with reader,
- ...
- records are terrible and boring, but "lens" is quite hard to use;
- GADTs are cool, but at first we can just validate input as anywhere else;
- LambdaCase rocks, but \x -> case x of is not that bad;
- ...
My favorite exercise for students is to write a small concurrent TCP server using "network-simple", so they learn about IO and STM.
- define your own sum types,
- use map, folds, and other higher-order functions well,
- use "fmap" and "do notation" for a bunch of concrete examples,
you are more than prepared to write good #Haskell!