[Haskell-cafe] Better writing about Haskell through multi-metaphor learning

Viktor Dukhovni ietf-dane at dukhovni.org
Mon Sep 20 17:50:52 UTC 2021


> On 20 Sep 2021, at 2:30 am, Joachim Durchholz <jo at durchholz.org> wrote:
> 
> The idea is that a monad is a tool to construct a pipeline inside a Haskell program.
> I think. It isn't my metaphor either, I have seen various people in this thread mention it in passing.

A "pipeline" is not necessarily a *static* pipeline.  Even in "bash" we
have conditional branching:

    $ seq 1 99 | while read i; do if (( i % 10 == 1 )); then seq $i | grep 0 | fmt; fi; done
    10
    10 20
    10 20 30
    10 20 30 40
    10 20 30 40 50
    10 20 30 40 50 60
    10 20 30 40 50 60 70
    10 20 30 40 50 60 70 80
    10 20 30 40 50 60 70 80 90

So IO and State and Maybe and Either all fit.

As noted a few times in this thread List takes multiple paths.  The
"non-determinism" (something that not always explained well, since
taking all paths is still rather deterministic) extends the simple
pipeline model.

The computation is still sequenced, it is just that a given stage can
invoke its "continuation" multiple times.

An intersting minimal model for the list monads is "jq", which is a small
functional language for manipulating JSON values.  It is basically the List
monad for JSON, but both evaluation and function composition are written as
simple-looking pipelines:

    value | function1 | function2 ...

But more advanced "jq" users know that a value or function can be
a stream (generator) of values:

    (value1, value2, ...) | function1 | function2 ...

    $ jq -n '(1,2,3,4) | select(. % 2 == 0) | range(.) | .+100'
    100
    101
    100
    101
    102
    103

So this is isomorphic to Haskell's List monad.  And yet, in part because
typically there's only one value on the left, and only one output on the
right, the naive "pipeline" model is a fairly good fit if, as needed,
one also admits "non-determinism".

Where pipelines really don't appear to me to be an adequate mental model
is "Cont".  Reifying continuations feels very different from even a
non-deterministic pipeline.  Even "programmable semicolon" likely does not
yield much intuition about "Cont".

But, to first approximation, and without suffering any harm thereby, pipelines
have worked well for me (and I expect others).  I know that's not the whole/real
story, I don't need the model as a crutch, but it works well enough, often enough
to remain a useful way of reasoning about the many situations in which it is
applicable.

-- 
	Viktor.


More information about the Haskell-Cafe mailing list