[Haskell-cafe] On finding the right exposition...
Viktor Dukhovni
ietf-dane at dukhovni.org
Fri Sep 17 19:47:19 UTC 2021
On Fri, Sep 17, 2021 at 05:02:09PM +0000, Richard Eisenberg wrote:
> > Was it literally just a single sentence introducing a new word for a
> > concept that made you "get it"? Could you elaborate? This is really
> > quite remarkable.
>
> For me, coming from a mostly Java background (but with a healthy
> dollop of functional programming thrown in the mix -- but no Haskell),
> the phrase that unlocked monads was "programmable semicolon".
No single exposition is optimal for all learners. Some are
visual-spacial, others verbal-sequential, and there are likely other
learning styles I've not heard of.
Therefore, even with good writing, some readers will have to work harder
at understanding the material than others, because they have to
translate the explanations into a form that works for them.
Also some readers are learning programming and Haskell at the same time,
while others are experienced programmers, but not in Haskell or another
ML-family or functional language.
A reader far removed from the target audience of the writer may find a
well written document largely unhelpful. There's no silver bullet.
I haven't yet run into a "Haskell the language" book for experienced
programmers that cuts to the chase and covers Haskell concisely a la
K&R, focusing much more on the language than on how to write code (only
as much code as it takes to minimally illustrate a language feature).
Such a book would be challenging, because beyond writing basic numeric
expresssions a large part of the language is needed all at once before
one can write even some fairly simple functions.
An off the cuff list of topics likely poorly ordered:
* Basic expressions
- Int, Word, Integer, Natural and Double
- Infix operators, associativity and precedence, parentheses
- Sections, (+), (.) and ($)
- let and where
- layout
* Program structure
- Function signature, head and body
- patterns and pattern bindings
- "case" and "if/then/else"
- guards and pattern guards
- modules, imports, and exports
* User defined types
- Algebraic data types, sums, products
+ Tuples
+ List (mention Array and Vector)
+ String (and mention Text)
+ Maybe
+ Either
- Newtypes
- Type aliases
- GADTs
- Existential types
* More standard types
- Array (immutable)
- Vector (immutable)
* Lazy evaluation and strictness
- Space efficiency, seq and BangPatterns
- ByteString strict, lazy and builders
- Text strict, lazy and builders
- Strict fields and StrictData
* Type classes and constraints
- Integral
- Monoid
- Semigroup
- Foldable
+ Strict and lazy folds
* Functors, Monads and Applicatives
- State and IO Monads
- map, fmap and ap
- File I/O
- Streaming
- Applicative option parsing?
* IO, ST and mutable values
- MVector
- MArray
... lots more ...
before long we have a book that's considerably larger than K&R. This
then leads to some frustration for the experienced programmer impatient
to learn the basics of the language and get productive right away
without relearning too much from the ground up.
But then perhaps even modern C++ or Java has a rather non-trivial
learning curve if one is starting from K&R C.
There may not be a book that reasonably efficiently brings an
experienced non-Haskell programmer to minimal proficiency, and
the separation of pure functions from I/O means having to learn
abstractions that don't come up in most other languages.
For me, the journey was worth it, and the right book would surely have
helped, (and would still help, I am far from the summit) but in the end
it still takes effort and time.
--
Viktor.
P.S. Re: mental models of monads:
Personally [verbal sequential], I find strained analogies unhelpful
and distracting, so no desk clerks shuffling forms for me.
I internalised Haskell monads, by implementing the Functor, Applicative
and Monad instances for Reader and State a few times from scratch. Once
those were solid, ReaderT and StateT and their MonadTrans instances.
Unsurpsingly, I have a mental model built around sequencing of internal
state updates while passing data from one state to use in choosing the
next state transition.
I do appreciate "programmable semicolon", but only *after* getting a
more concrete intituition for the standard examples.
More information about the Haskell-Cafe
mailing list