Here is an half-baked idea how to make monads more functional.<br>It&#39;s too wild to be implemented in haskell.<br>But maybe you are interested more in ideas than implementations, <br>so let&#39;s start with monad class<br>
<br>class Monad m where<br>    return :: a -&gt; m a<br>    (&gt;&gt;=)  :: m a -&gt; (a -&gt; m b) -&gt; m b<br><br><br>I think monad&#39;s methods are misleading, let&#39;s rename them<br><br>class Monad m where<br>    idM  :: a -&gt; m a<br>
    (*$) :: (a -&gt; m b) -&gt; m a -&gt; m b<br><br><br>We can see that `return` is a monadic identity and the `bind`<br>is an application in disguise. So now we have two applications.<br>It&#39;s standard `($)` and monadic `(*$)`. But they are application.<br>
Well isn&#39;t it something like `plusInt` and `plusDouble`?<br>Maybe we can devise single class for application. Let&#39;s<br>imagine a special class `App`<br><br>class App ?? where<br>    ($) :: ???<br><br>As you can see it&#39;s defined so that we can fit<br>
monads and plain functions in this framework. Moreover<br>if we redefine this class than whitespace is redefined<br>automatically! So `($)` really means *white space* in haskell.<br><br>`idM` is interesting too. In standard world we can safely<br>
put `id` in any expression. So when we write <br><br>    f = a + b<br><br>we can write<br><br>    f = id (a + b)<br><br>or even<br><br>    f = id ((id a) + (id b))<br><br>meaning doesn&#39;t change. So if we have special class `Id`<br>
<br>class Id f where<br>    id :: ???<br><br>Again you can see that monads fit nicely in the type.<br>Why do we need this class? Whenever compiler gets an type mismatch,<br>it tries to apply method from `Id` class, if it&#39;s defined ofcourse.<br>
<br>But we have a class called `Category`, `id` belongs to it:<br><br>class Category (~&gt;) where<br>    id   :: a ~&gt; a<br>    (&gt;&gt;) :: (a ~&gt; b) -&gt; (b ~&gt; c) -&gt; (a ~&gt; c)<br><br><br>Let&#39;s pretend that `(&gt;&gt;)` is reversed composition `(.)`.<br>
It&#39;s interesting to note that there is another formulation<br>of &#39;Monad&#39; class. It&#39;s called Kelisli category.<br><br>class Kelisli m where<br>    idK  :: a -&gt; m a<br>    (&gt;&gt;) :: (a -&gt; m b) -&gt; (b -&gt; m c) -&gt; (a -&gt; m c)<br>
<br>Here again let&#39;s forget about monad&#39;s `(&gt;&gt;)` for a moment, <br>here it&#39;s composiotion. `Kleisli` is equivalent to `Monad`.<br><br>If we can define `Category` instance for `Kleisli`, so that<br>somehow this classes become unified on type level we<br>
can define application in terms of composition like this:<br><br>f $ a = (const a &gt;&gt; f) ()<br><br>And we can get application for monads (or kleislis :) ).<br><br>Implications:<br><br>Maybe someday you wrote a function like this:<br>
<br>foo :: Boo -&gt; Maybe Foo<br>foo x = case x of<br>    1 -&gt; Just ...<br>    2 -&gt; Just ...<br>    3 -&gt; Just ...<br>    4 -&gt; Just ...<br>    5 -&gt; Just ...<br>    6 -&gt; Just ...<br>    7 -&gt; Just ...<br>
    _ -&gt; Nothing<br><br>with `idM` rule you can skip all Just&#39;s<br><br>You can use white space as monadic bind. So functional application<br>can become monadic on demand. Just switch the types.<br><br><br>Implementation:<br>
<br>I&#39;ve tried to unify `Category` and `Kleisli` with no luck.<br>Here is a closest sletches:<br><br>simplest sketch requires type functions :(<br><br><br>instance Monad m =&gt; Category (\a b -&gt; a -&gt; m b) where<br>
    ...<br><br><br>the other one too :(<br><br>class Category (~&gt;) where<br>    type Dom (~&gt;) :: * -&gt; *<br>    type Cod (~&gt;) :: * -&gt; *<br><br>    id   :: Dom (~&gt;) a -&gt; Cod (~&gt;) a<br>    (&gt;&gt;) :: (Dom (~&gt;) a ~&gt; Cod (~&gt;) b) -&gt; (Dom (~&gt;) b ~&gt; Cod (~&gt;) c) -&gt; ...<br>
<br><br>instances<br><br>type Id a = a  -- :(<br><br>instance Monad m =&gt; Category (a -&gt; m b) where<br>    type Dom (a -&gt; m b) = Id<br>    type Cod (a -&gt; m b) = m<br><br>    ...<br><br><br>