On 10/17/08 08:12, Daniel Fischer wrote:

Thanks very much Daniel.

Am Freitag, 17. Oktober 2008 14:42 schrieb Larry Evans:
On 10/17/08 07:39, Larry Evans wrote:
The attached code produces error:
<-- cut here --
[snip]
{- Purpose:
  Explore how to mix 'assignments' inside do.
Motivation:
  Instead of:
let { v0 = e0 ; v1 = e1 }
    in do
      { print v0
      ; print v1
      }
  which is hard to read, recode above as:
    do
      { v0 = e0
      ; print v0
      ; v1 = e1
     ; print v1
      }

That would have to be
do let v0 = e0
   print v0
   let v1 = e1
   print v1

or
do v0 <- return e0
   print v0
   v1 <- return e1
   print v1

(better (?):
do print $ e0
   print $ e1
)

At first, the |let v = e| combination looked best (less typing).
However, my actual e0 was more complicated:

      array_complete
      [ Expr   <== Op0 GramOne
      , Term   <== Op0 GramOne
      , Factor <== Op0 GramOne
      ]

where <== was a binary operator which just produced a tuple pair.
I wanted to keep the expression on multiple lines because it's
easier to read.  The <== was defined to make the expression
look more like grammar productions (the Op0 GramOne is not
the final rhs.  That's only for testing purposes.).

Unfortunately, using let with the multiline rhs failed to
compile (due, I guess, to some layout rules, which I find
difficult to fathom).  So, I tried the | v <- return e|
combination.  This worked although I had to surround e with
parenthesis to enable compilation with multiple lines:

  ; gram_eqs::GramEqs ArithInp ArithVar <- return
      (array_complete
      [ Expr   <== Op0 GramOne
      , Term   <== Op0 GramOne
      , Factor <== Op0 GramOne
      ])
  ; putStr "gram_eqs="
  ; print gram_eqs

I didn't use the last combination |print $ e0|
because e1 may use v0.  IOW:

  v0 <- return e0
  v1 <- return ...v0...

  which is easier to read and more intuitive for
  c++ programmers.

"intuitive for c++ programmers" is dangerous, the languages are very different, and one shouldn't gloss over that. The different syntax should help to not confound the languages.

OK, but I'm finding it very difficult to figure out how to do
something that's very simple in c++:

  ; calculate e0
  ; store e0 in v0
  ; print v0
  ; calculate e1 using possibly v0
  ; store e1 in v1
  ; print v1

However, apparently, in haskell, the operands on each side of the ';'
must be "compatible".  Hmmm, I remember seeing a translation of
more complex haskell statments/expression to simpler ones...
looking...

  http://haskell.org/onlinereport/exps.html#sect3.14

Mea culpa :(  I should have read that first.  Then
a would have realized:

  (v0 <- e0) >> putStr "v0"

would not have worked because, I guess:

  e0 >> putStr "v0"

would not work. OOPS, sect3.14 has a specialization on the pattern p<-e.
That specialization is harder to understand.  I'll work on it :)

[snip]

remember that in

do value <- action
   statements -- using value (or not)

action and statements must belong to the same monad. In your code above, the 'action' [999] has type Num a => [a], so the monad is [], but putStr "v0=" has type IO (), the monad is IO. So the binding v0 <- [999] and the statement putStr "v0=" can't appear in the same do-block.

If what you want is "for every member of some list, do some monadic action", you need mapM/mapM_ resp forM(_):

Nope.  I just want to trace through various stages in translation of
a language grammar(a set of "grammar equationss") to a corresponding
set of equations defining the lookahead sets for that grammar.
So, I want the do{...} to just be a sequence of (calculate value; print value} where calculate value may use previously calculated values).

Thanks for you help.

-regards,
Larry

_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to