FunSpIns - Drawing a Rectangle

Inspired by Rob Ashton’s series “Learn functional programming with me

It probably is a good idea to introduce to some basic syntax:

A Haskell function call:

letme “die” “twice”

Here, letme would be the function, whereas the remaining parts would be arguments passed to it.

A Haskell function definition:

letme:: String -> String -> String
letme x y = x ++ " " ++ y

In Haskell, Types are sooper-important. In this example we have specified the signature of the function explicitly. As a sidenote, we don’t have to do that, in this case Haskell would have inferred the following signature:

*Blog> :t letme
letme :: [Char] -> [Char] -> [Char]

*) btw, this is taken from the ghci the interactive way to talk with Haskell.

Huh, not as generic as we thought, how come? - Reason’s the ” ” in the function definition. Anyway, on to other stuff.

Assuming you got Haskell ready to talk to SDL (see previous post in the fun spins series), we need to think about how to draw a rectangle.

Drawing a rectangle certainly is IO, hence that kind of thing will have to happen in Haskell’s IO context. In that context it is a fairly OK thing to have an entry point - leering a bit at animal machine’s series, we can get us a nice lil’ entry point:

module Game where
import Graphics.UI.SDL as SDL
main :: IO ()
main = do
SDL.init [SDL.InitEverything]
SDL.setVideoMode 640 480 32 []
SDL.setCaption "Draw Rectangle"
eventLoop
SDL.quit
print "done"
where
eventLoop = SDL.waitEventBlocking >>= checkEvent
checkEvent (KeyUp _) = return ()
checkEvent _ = eventLoop

Woa, OK - main is a thing that runs in an IO context and returns nothing ( hence the () ). >>= has a type definition of

Monad m => m a -> (a -> m b) -> m b

Which reads along the lines of

Given some thing of type a running in a context and a function that accepts something of type a and returns some type b running in the same context, get me the result of said function, wrapped in that context we mentioned.

I doubt that this helps you, for now it doesn’t help me a lot, but I think it is pretty clear what effect the code has. We have ourselves a nice event loop which I am sure will come in handy later on.

So, what about that frikkin’ rectangle?

module Main where
import Graphics.UI.SDL as FX
main :: IO ()
main = do
FX.init [InitVideo]
FX.setVideoMode 640 480 32 []
canvas <- FX.getVideoSurface
FX.fillRect canvas (Just (Rect 25 25 100 100)) (Pixel 0xFFFFFF)
FX.flip canvas
eventLoop
FX.quit
where
eventLoop = FX.waitEventBlocking >>= checkEvent
checkEvent (KeyUp _) = return ()
checkEvent _ = eventLoop

Paints us a white rectangle at position 25,25 with a width and height of 100 pixels.

A word on running the program

You can either