
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