3

I got stuck on coding the main SF for a Mario like game I am writing for fun. Here is the code that does not parse:

master_combine = proc pi -> do 
                            -- rec cgg <- player_update >>> (initial_game --> bounds_updater) >>> iPre initial_game -< (pi, cgg)
                            rec gs  <- player_update >>> (initial_game --> bounds_updater) -< (pi, dgs)
                                dgs <- iPre initial_game -< gs
                            returnA -< gs

And this is the code that parses and executes ok:

master_combine = proc pi -> do 
                            rec cgg <- player_update >>> (initial_game --> bounds_updater) >>> iPre initial_game -< (pi, cgg)
                            -- rec gs  <- player_update >>> (initial_game --> bounds_updater) -< (pi, dgs)
                            --  dgs <- iPre initial_game -< gs
                            returnA -< cgg

Note that i preserved both versions in the same code block with comments to make the difference more visible.

In principle i would like to create a negative feedback loop with a small delay so that i can pass the transformed game around and not have to switch functions. The output goes to a "draw" SF like this:

mainSF = parseInput >>> master_combine >>> draw

In the first version i try to use intermediate names gs (game state) and dgs (delayed game state). The error is signaled on the line starting with dgs.

In the second version, the one that works for me, I had to write the entire SF in one line.

I would like to use the first version of the code because i need to extend the functionality by connecting additional SFs that imply negative feedback loops.

I keep searching for help on rec in Arrow "do" notation and i always find the same examples that emphasize proper code indentation. But i indent with Sublime and the spacing looks fine to me. Is there another way ? Brackets, curly brackets? Anything?

  • `rec gs <- ..` and `dgs <- ..` should start on the same column. That is *the* indentation rule - everything in a "block" starts on the same column. And the first syntactic element of the block determines what the indentation level should be. As an aside, yes you can use curly braces to avoid indentation issues - `do \n x \n y` becomes `do { x ; y }`. – user2407038 Apr 01 '16 at 19:20
  • @user2407038: he wants to use `dgs` in the definition of `gs`, which means he needs its definition to be inside the `rec`. – Jonathan Cast Apr 01 '16 at 20:31

1 Answers1

3

I notice you're using tabs. I'm guessing your tabs are set to 4 spaces? Haskell's tabs are always set to 8 spaces. Either change your tab settings in Sublime to 8 spaces or set Sublime to expand tabs to spaces and it should work.

(Obviously you have to change the tab before dgs to four spaces either way).

Another option is to put a newline (and indent) after rec, in which case it doesn't matter what length your tabs are (since you're being consistent about using tabs):

master_combine = proc pi -> do 
                            -- rec cgg <- player_update >>> (initial_game --> bounds_updater) >>> iPre initial_game -< (pi, cgg)
                            rec
                                gs  <- player_update >>> (initial_game --> bounds_updater) -< (pi, dgs)
                                dgs <- iPre initial_game -< gs
                            returnA -< gs
Jonathan Cast
  • 4,569
  • 19
  • 34
  • Epic win! Thanks man. Would be nice to have curly brackets support for rec code blocks. Like in the case of do notation. I code on a couple of machines with slightly different settings so having to rely on indentation to specify some expression is not very nice. – Razvan-Ionut Olteanu Apr 02 '16 at 10:24