Mon Aug 1 21:39:42 CEST 2011

Better syntax

Is there a better way to write this?

f5 x = let_ (x  * x)  $ \x1 ->
       let_ (x1 * x1) $ \x2 ->             
       let_ (x2 * x2) $ \x3 ->             
             x3 * x3

I don't think the wrapping used is compatible with do notation.
I.e. something like this:

f6 x = do
   x1 <- x * x
   x2 <- x1 * x1
   x3 <- x2 * x2
   x3 * x3

Which has the not-so-useful type:

  :: (Num (m (m (m (m b)))),
      Monad m,
      Num (m (m (m b))),
      Num (m (m b)),
      Num (m b)) =>
     m (m (m (m b))) -> m b

The closest I get to something useful is this:

v = return

f7 x = do
  x1 <- v $ x * x
  x2 <- v $ x1 * x1
  x3 <- v $ x2 * x2
  v $ x3 * x3

The type of v can probably be restricted, but it still looks ugly.  It
seems best to just use template haskell to generate a new binding form
that expands to let_

What would help is to be able to lift all the num monops and binops to:

              a -> m b   and   a -> b -> m c

Too bad that won't work, since the prototypes aren't compatible:

*Main> :t (+)
(+) :: (Num a) => a -> a -> a

Conclusion: do notion would work if we make the monad explicit.
However, the approach taken leaves the monad behind the scenes,
leaving only the language syntax as the main player.