# [Haskell-cafe] some help on do and preservingMatrix

Jason Dusek jason.dusek at gmail.com
Thu Nov 26 15:13:47 EST 2009

```2009/11/26 Zsolt Ero <zsolt.ero at gmail.com>:
> My very basic question is that how do I generally repeat a command
> many times? I understand "do" can do it, but it's not clear to me how
> to use it and how it works.
>
> So if I would like to write the following in one line, how could I write it?:
> spiral 0.7
> spiral 0.8
> spiral 0.9
> spiral 1.0
>
> I don't understand in which cases I can use "map something
> [0.7,0.8..1]" and in which cases I need do and how could I map using
> do.

Say we have something to draw a spiral:

spiral                  ::  (Floating f) => f -> IO ()

So `spiral` takes a floating point number and gives us a
program in the IO monad that returns `()`.

We wish to draw several spirals. Here's one way:

draw_them_all            =  do
spiral 0.7
spiral 0.8
spiral 0.9
spiral 1.0

Here's another way:

another_way              =  do
sequence_ several_spirals
where
several_spirals       ::  [IO ()]
several_spirals        =  map spiral [0.7,0.8,0.9,1.0]

Or even:

another_way'             =  sequence_ several_spirals
where
several_spirals       ::  [IO ()]
several_spirals        =  map spiral [0.7,0.8,0.9,1.0]

case, programs in the IO monad). If you have a list of monadic
values you can use `sequence_` to join them together into one
then `sequence_` to join them together in order.

> From the tutorial, I could write this line, which works, but I
> don't really know what does mapM_ and preservingMatrix do.

The function `mapM_` is simply the composition of `sequence_`
and `map`.

mapM_ f list             =  sequence_ (map f list)

As for `preserveMatrix`, it is some OpenGL thing; probably
what it does is ensure that any changes you make to one of the
matrices that make up the rendering state are undone once you
exit the enclosed computation.

--
Jason Dusek
```