It is actually easy to play with this idea using Template Haskell,
modulo some syntax.  I implemented a little library called MEval last
year that exports a TH preprocessing function

  meval :: Meval a => Q a -> Q a

and a "magic" variable

  p :: Monad m => m a -> a

The preprocessing function will perform Greg's translation whenever it
finds Meval.p applied to something inside a do statement.

I find this approach useful especially when you want to evaluate monadic
arguments inside arithmetic expressions or infix expressions in general.
 Then, the combinator approach provided with Control.Applicative tends
to obscure the expressions.  Other examples are case and if expressions
in which you want to scrutinize monadic expressions.

I attach a tar file with the library and an example program, feel free
to hack away on them.

Cheers,
Magnus

Simon Peyton-Jones wrote:
> Another alternative (which I got from Greg Morrisett) that I'm toying with is 
> this.  It's tiresome to write
> 
>         do { x <- <stuff1>
>            ; y <- <sutff2>
>            ; f x y }
> 
> In ML I'd write simply
> 
>         f <stuff1> <stuff2>
> 
> So Greg's idea (or at least my understanding thereof) is to write it like 
> this:
> 
>         do { f $(stuff1) $(stuff2) }
> 
> The idea is that a "splice" $e must be lexically enclosed by a 'do', with no 
> intervening lambda.  It's desugared to the code above; that is, each splice 
> it pulled out, in lexically left-right order, and given a name, which 
> replaces the splice.
> 
> Of course it doesn't have to look like the above; the rule applies to any do:
> 
>         do { v <- this; foo $(h v); y <- f $(t v v); ...etc }
> 
> The "linearise the splices" rule is quite general.
> 
> Don't burn any cycles on concrete syntax; I know the $ notation is used for 
> Template Haskell; one would need to think of a good syntax.  But the idea is 
> to make it more convenient to write programs that make effectful calls, and 
> then use the result exactly once.
> 
> Anyway, this'd do what the original proposer wanted, but in a much more 
> general way.
> 
> Just a thought -- I have not implemented this.
> 
> Simon
> 
> | -----Original Message-----
> | From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Adde
> | Sent: 10 July 2007 21:40
> | To: [EMAIL PROTECTED]
> | Cc: haskell-prime@haskell.org
> | Subject: Re: Make it possible to evaluate monadic actions when assigning 
> record fields
> |
> | On Tue, 2007-07-10 at 17:04 +0000, [EMAIL PROTECTED] wrote:
> | > Isaac Dupree <[EMAIL PROTECTED]> wrote:
> | >  >
> | >  > Adde wrote:
> | >  > >  tmp <- foo
> | >  > >  return Bar {
> | >  > >    barFoo = tmp
> | >  > >  }
> | >  >
> | >  > There is a feature being worked on in GHC HEAD that would let you do
> | >  >
> | >  >   do
> | >  >    tmp <- foo
> | >  >    return Bar{..}
> | >  >
> | >  > which captures fields from everything of the same name that's in scope.
> | >  >   I think this would also satisfy your desire.
> | >  >
> | >
> | > I guess this means I could write:
> | >
> | >
> | > data D = C {field1 :: Bool, field2 :: Char}
> | >
> | > f x = do
> | >   field1 <- foo1
> | >   field2 <- foo2
> | >   field3 <- foo3
> | >   other stuff
> | >   return C{..}
> | >
> | >
> | > instead of
> | >
> | >
> | > f x = do
> | >   tmp1 <- foo1
> | >   tmp2 <- foo2
> | >   field3 <- foo3
> | >   other stuff
> | >   return $ C { field1 = tmp1, field2 = tmp2 }
> | >
> | >
> | > This has a dangerous feel to it ---
> | > extending the definition of D to include a field field3
> | > may have quite unintended consequences.
> | >
> | >
> | > What I am missing most in the record arena
> | > is a functional notation for record update, for example:
> | >
> | > {^ field1 }  =  \ f r -> r {field1 = f (field1 r)}
> |
> | I agree, capturing variables without asking is just scary.
> | While I'm pretty biased I still think my suggestion solves the problem
> | in a cleaner, more consistent way.
> |
> | /Adde
> |
> | _______________________________________________
> | Haskell-prime mailing list
> | Haskell-prime@haskell.org
> | http://www.haskell.org/mailman/listinfo/haskell-prime

Attachment: MEval.tar.gz
Description: GNU Zip compressed data

_______________________________________________
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime

Reply via email to