Sat Jul 21 22:02:05 EDT 2018
Getting deep into misunderstood abstractions.
What is the relation between:
- do-notation / ANF
- tuple-shuffling + linear Kleisli conmposition
In the former, there is a local context of names available that gives
a bit of a spaceous feel, while simply composing individual Kleisli
arrows, and pushing this local context through typles feels very
But are these equivalent? I'm thinking they must be. But why does
ANF seem so much more powerful? I.e. it seems as if linear
tuple-shuffling cannot change the structure of composition, but ANF
clearly can: just use "if" to pick two different monadic values.
Why is this so hard to understand?
Why does my intuition have these gaps?
Maybe time, once and for all, to clear this up.
Early on when working on Staapl and just reading about Haskell without
actually understanding, I thought monads were the same as the state
Now I come to a similar, but different situation, where I'm thinking
that tuple-shuffling is the same as ANF form.
So a question is: can you implement "if" with tuple shuffling? What
would it's type look like?
if' :: (Bool, m a, m a) -> m a
Which is just the uncurried version of regular if.
But note that (m a) is a monadic value, not a Kleisli arrow. Does
that matter? Probably not.
Again, why am I so confused about this? It is an old one... The
answer should be straightforward if it is meaningful. Is there a type
error in the idea?
Maybe rephrase. Why is it at all possible to have this context? How
can a Kleisli arrow "down the chain" see the lexical context that was
also available to previous compositions? Obviously, it works. Why do
I find it so strange?
Often when these things happen, it is about asking the wrong,
meaningless question. An appropriate question in this context is: can
do notation / bind chaining be written in terms of kleisli composition?
\ma mb -> do
a <- ma
b <- mb
return $ a + b
\ma mb -> ma >>= (\a -> mb >>= (\b -> return $ a + b))
So again, it's completely obvious that this is possible
(algebraically). Why do function abstraction and (>>=) interact in
such an un-intuitive way?
Simpler, with a unary function
\ma -> ma >>= (\a -> return $ a + 1)
Maybe just a bit too much wine to do these kinds of things... I've
noticed in the past weeks getting more intense about Haskell work that
I've gotten stuck on intuitions that are just plain wrong, while
sleeping on it made it absolutely clear what was going on without
getting into the generated "intuitive madness".