Humbly simple F# Maybe monad application scenario

Introduction

I won’t turn this article in another spammish claim about monads and functional programming. If you are interested in digging inside it, from a theoretical point of view, I suggest you start here to get the gist of what I’m talking about. Let’s say briefly that monads are a useful and clever way to write safe and more beautiful code. For once let’s focus to the practical side of the question, without further ado.

A simple scenario

Suppose you are working on a real world application for a supermarket, and you need to create a simple data structure to store products, with their IDs and prices. The pair (key,value) immediately make the word dictionary to spring up in mind. So you want to create a data structures that embeds a dictionary and you want also to expose a bunch of APIs for inserting a new product and to get the price of a product given his ID. In a standard Object Oriented language you would end up writing a thing like this:

class Inventory
{
public:
    Inventory();
    void Stock(const std::string& id, float price){ inventory_[id] = price; }
    float Price(const std::string& id){ ... }
private:
    std::map < std::string, float> inventory_;
};

Let’s focus our attention to the Price method. You are asking the price for a certain product, given his id. This translates in a lookup inside our inventory map. But what about if the product doesn’t exists? Good programmers would throw an exception, that will be captured at run-time somewhere, leading to a code that we know very well, and that’s not so beautiful to look at:

float sumPrices(const Inventory& i, const std::string& id1, const std::string id2)
{
    try
    {
      float p1 = i.Price(id1);
      float p2 = i.Price(id2);
      return p1 + p2;
    } catch (ProductNotFoundException e)
    { //handle somehow }

}

Monads and F# comes to the rescue, allowing us to write a great deal more beautiful code than this. Let’s see how.

Separating the impure from the pure

Now let’s move our problem in the F# and .NET world. We need to create a type to model an Inventory, expose the above mentioned APIs and also provide a mechanism to sum prices, printing the total whether all the id were found, an error otherwise. The simplest thing to do is to reuse one of the existing .NET classes, to be precise a System.Collections.Generic.Dictionary:

type ProductId = string
type Price = float

type Inventory() =
    let inv_ = new System.Collections.Generic.Dictionary<ProductId, Price>()

    member this.Stock (id : ProductId) (price : Price) =
        inv_.Add(id, price)

So, we have defined two type synonyms for a better understanding of the problem, this new type as well as a member to stock a new product, given its id and its price. Now we must be wary about writing the Price member, because in case of unsuccessful lookup .NET throws a
System.Collections.Generic.KeyNotFoundException, which is not good in our pure functional world. We elegantly solve this using the Option type. We can see Option as a type (to be precise it’s a discriminated union) that represent only two possibles values: A success value where it wraps up the result in the type constructor Some, and a failure which translates to the value None:

type Option<'a> =
    | Some of 'a
    | None

Now we can separate the “impure”, null-mined .NET world from our domain:

    member this.Price (id : ProductId) =
        try
            Some(inv_.[id])
        with
            | : ? System.Collections.Generic.KeyNotFoundException -> None

Now every time we ask for a product, we don’t take the risk of raising an exception, while having an Option<Price> back give us a great power, because we can pattern match against an Option type to discriminate a function behavior according to the value. Little example:

>let inv = new Inventory();;
val inv : Inventory
> inv.Stock "foo" 10.0;;
val it : unit = ()
> inv.Price "foo";;
val it : Price option = Some 10.0
> inv.Price "doesnotexists";;
val it : Price option = None

Pretty neat isn’t it? Now that we have this nice type to work with, let’s solve the second part of the problem: how to sum two or more product’s prices, displaying the sum or an error messages if some product doesn’t exist. To achieve our goal, we’ll use the Maybe monad, implemented inside the FSharpx library.

Concatenating computations

I won’t bother you with jabbering about computational expressions and so on, but I’ll show you the code. Let’s first create a function that takes the computation final result (under the form of  an Option<Price>) and print a success or a failure message:

let reporter (priceSum : Price option) : unit =
    match priceSum with
    | Some(p) -> printfn "Total price: %g." p
    | None    -> printfn "One or more id(s) not found."

Nothing particularly amazing here. Now let’s create a new infix function (for the lay people: a function that can be invoked between two parameters, in an infix way). Bear in mind that this is not always the way to go, because creating too much weird operators can lead to a less readable code, but here we won’t care and proceed anyway:

let inline (|@|) (p1 : Price option) (p2 : Price option) =
    maybe{
        let! v1 = p1
        let! v2 = p2
        return! Some(v1 + v2)
    }

Ok, so let’s clarify things a bit. The easiest way to think about monads, in my opinion, is like a sort of Lego pieces, each piece may contain a value (or not, it depends).

In this case in order to concatenate our computations we need to concatenate only the same Lego pieces together. Do you remember in the primary school when teachers keep you telling that you can’t sum pears with apples? The concept is more or less the same. So we can sum and combine only monads of the same type. But how? The answer lies in the lines of code above. With the operator let! we performs a sort of destructuring  (to be precise a monadic binding) which means that we peek inside our Lego piece and we take out the content, whether it exists or not. Yes, whether it exists or not. In this specific case, the Maybe monad ensures us that failure is propagated. In other terms, if you “sum” a Some(value) with None, we will obtain None, because None is the Zero value for that monad. I don’t want to dig too much inside this theoretical stuff, but every monad has it’s zero, a value you can sum against without having an impact on the overall computation (think about the (+) operator, 0 (zero) is the numeric value you can sum indefinitely without affecting the result). All this babbling means that if v1 and v2 binds to a “real” float, the result will be wrapped inside a Some(v1+v2), which is the real sum. Otherwise a None will be returned. Gosh, I hope is clear enough. To clarify, here is an example of our new operator in action:

> let price1 = Some(10.0);;
val price1 : float option = Some 10.0
> let price2 = Some(4.90);;
val price2 : float option = Some 4.9
> price1 |@| price2;;
val it : Price option = Some 14.9
> price1 |@| None;;
val it : Price option = None

Seen? Pretty cool, isn’t it? No meaningless exceptions, no null spreading everywhere. Just simple type who are concatenated to form a result.

The final touch: making it more general

As final step we’ll write a simple function that takes a list of ids, an inventory and prints our total whether it “exists” (i.e if every product is inside the inventory) or failure message if something goes wrong. Here we go:

let sumAndReport (inventory : Inventory) (ids : ProductId list) : unit =
    let basket = List.map (fun pid -> inventory.Price(pid)) ids
    in List.reduce (fun p1 p2 -> p1 |@| p2) basket
    |> reporter

It should be clear enough. If you are an F# newcomer, the |> is the pipeline operator, is passes the result on the right side to a function on the left. In worth noting that when we get the list of products with the basket let binding, we don’t care whether those products exist! In fact, monads (in this case the Maybe monad) abstract the computation incapsulating a success or a failure in a way that we can control, combine and mix without worrying about the rest. And this is only the tip of the iceberg!

I redirect you to this gist, where you’ll find the full source code, as well as a couple of data for testing purpose.

Conclusions

Monads are a clever idea to encapsulate a lot of things: failure, state, IO, etc.. and having monads support in F# is simply awesome. The real world can benefit from this strange creatures, I believe. In an upcoming article we’ll see how make our code even more simple, beautiful and short thanks to some feedback provided on the gist from the user mausch.

Stay tuned!

A.

Annunci

Setting up a simple Mogre Application in F#

Game engine panorama is pretty crowded. There are open source ones, commercial ones and so on. Ogre is properly defined as an “Open Source 3D Graphics Engine”, which means that it is at a lower level than a fully-fledged Game Engine. You can use Ogre for 3D rendering and assemble your homemade Game Engine picking up other useful library, for example OpenAL for the sound processing and Nvidia PhysiX for the Physics. This way has been followed, for example by NeoAxis Engine.

Mogre  (quoting from the official site) ” is an advanced .NET wrapper for OGRE. It can be used by C#, Visual Basic etc. […]  The pure graphic rendering speed is similar to Ogre C++ applications, because the calculations are done by the same Ogre core library (written in C++) and the wrapped interactions are quite fast”. Since premises seemes encouranging, I’ve given Mogre a try, intrigued by the possibility to use F# for game developement (or at least for same experiments).

Installation

The installation is a piece of cake, thanks to an installer downloadable from the official site. Once installation is completed, you should have a directory labeled “MogreSDK” inside your C folder (or whatever). The next step is to build all the bundled examples (they are for 90% the same of the original Ogre package) clicking on a command script inside the SDK folder (BuildSamples.cmd for the lazy people). Now you can start the “SampleBrowser” program and test this stuff, for example “Mogre in Windows Forms”:

Cool, it worked!

Setting up a simple F# Project

Setting up an F# Project is not incredibly difficult (is pretty straightforward) thanks to a bunch of libraries called “Mogre Wiki Tutorial Framework” especially gathered to simplify the initial Mogre setup. As we can read on the Wiki this “Mini Framework” is not the ideal environment to work with, but only an aid to get started quickly with Mogre without struggling too much. As scaffolder we’ll use the Visual C# project downloadable from here (it targets .NET 4.0). Let’s see what it contains:

The “bin” directory contains all the required .dll for make our example works, and the “app.config” file is important as well, because it allows mixing assemblies compiled against different .NET versions. So let’s create another project, this file an F# solution (as Application type, leave “F# Application”), and then copy folders “bin” and “Media” and “app.config” in the newly created project. This is how the project will look like (ignore the obj directory, obviously will be generated after a successful compile):

Now the funniest part, write a program that do something useful.

Retrieve, Reuse, Revise, Retain

Before taking a leap inside the actual program, remember to add the required references for your project: you will need at least three of them: “Mogre”, “Mogre.TutorialFramework” and “MOIS”. You will found the dlls inside the bin directory. When you are ready, this is what’s inside my Program.fs:

open Mogre
open Mogre.TutorialFramework
open System

type SimpleApp() =
    inherit BaseApplication()

    override this.CreateScene() =
        this.mSceneMgr.AmbientLight <- new ColourValue(1.0f, 1.0f, 1.0f)
        let ent = this.mSceneMgr.CreateEntity("Head", "ogrehead.mesh")
        let node = this.mSceneMgr.RootSceneNode.CreateChildSceneNode("HeadNode")
        node.AttachObject(ent)

let app = new SimpleApp()
app.Go()

I’m not getting through it, because it’s a mere porting from the equivalent C# code. Once again, F# succintness and .NET thight intregration allows us to write compact and elegant code. One last subtle thing: I’ve encountered an error running my project, related to the mix of assemblies targetting different .NET version. Do you remeber the app.config file? There is a line which solves exactly this issue, but you have to copy it inside the executable directory in order to make all work. You can elegantly solve the problem with a post build rule (Project properties -> Post build event):

copy $(ProjectDir)app.config $(TargetDir)$(TargetFileName).config

And now you’ll (hopefully) be able to run your code!

You can download the full project on GitHub here.

Cheers,

Alfredo

The power of the big

Wow…

I’ve been quoted into a sort of report about F# and XNA development (Btw, I’ve only tweaked a bit a source code found on the net, just to learn a bit F# and XNA):

http://geekswithblogs.net/clingermangw/archive/2011/01/28/143679.aspx

I’m really surprised due to the echo of F# and XNA all over the internet… I mean, I’ve spent hours playing and writing about other awesome functional languages (Haskell, Scheme, Common Lisp, Clojure) but I’ve never been quoted, because “Speaking about Common Lisp and other crazy stuff is not cool”. This is sad, really sad.

On the other side, I’m very proud of have been cited somewhere 😛 (despite I haven’t done nothing special)

Bye,

Alfredo

 

Cow Pong: A simple Xna game in F#

F# is akin of melting pot language, including some interesting features from various functional languages like Haskell, OCaml and so on. It is very succint, readable and it is ML-based.
I’ve realized a simple Pong-clone game using the XNA framework in F#, and this is the result:

// A semiserious game // Learn more about F# at http://fsharp.net open System open Microsoft.Xna.Framework open Microsoft.Xna.Framework.Graphics open Microsoft.Xna.Framework.Input open Microsoft.Xna.Framework.Content type Paddle(posX : int, posY : int) =     let speed = 10     let x = posX     let mutable y = posY     static member W = 50     static member H = 80     member this.X with get() = x     member this.Y with get() = y and set v = y <- v     member this.Bounds         with get() = new Rectangle(x - 100, y - Paddle.H / 2, Paddle.W, Paddle.H)     member this.Move (keyUp : Keys) (keyDown : Keys) =         let ks = Keyboard.GetState()         if ks.IsKeyDown(keyUp)             then y <- y - speed         if ks.IsKeyDown(keyDown)             then y <- y + speed type Ball() =     let mutable x = 0     let mutable y = 0     let mutable vx = 0     let mutable vy = 0     let mutable number_of_bounce = 10     static member W = 20     static member H = 20     member this.Number_of_bounce         with get() = number_of_bounce and set v = number_of_bounce <- v     member this.X with get() = x and set v = x <- v     member this.Y with get() = y and set v = y <- v     member this.Bounds         with get() = new Rectangle(x - Ball.W / 2, y - Ball.H / 2, Ball.W, Ball.H)     member this.BounceX() =         this.Number_of_bounce <- this.Number_of_bounce + 1         vx <- -vx     member this.BounceY() = vy <- -vy     member this.Start (velX : int) (velY : int) =         vx <- velX         vy <- velY     member this.Update() =         x <- x + (int (this.Number_of_bounce/10))*vx         y <- y + (int (this.Number_of_bounce/10))*vy     member this.Collide (p : Paddle) = this.Bounds.Intersects(p.Bounds) type Game1() as this =     inherit Game()     let graphics = new GraphicsDeviceManager(this)     let contentManager = new ContentManager(this.Services)     let mutable spriteBatch = null     let mutable texture = null     let mutable left_paddle = null     let mutable background = null     let mutable ball_texture = null     let left = new Paddle(Paddle.W * 2, 300)     let right = new Paddle(820, 300)     let ball = new Ball()     let rand = new Random()     let mutable leftScore = 0     let mutable rightScore = 0     let clampY x : int =         if x < Paddle.H / 2 then Paddle.H / 2         else if x > 600 - (Paddle.H / 2) then 600 - (Paddle.H / 2)         else x     let reset (b : Ball) =         let mutable x = 0         let mutable y = 0         if rand.Next() % 2 = 0 then x <- -3 else x <- 3         if rand.Next() % 2 = 0 then y <- -3 else y <- 3         b.X <- 400         b.Y <- 300         b.Number_of_bounce <- 10         b.Start x y     let bounce (b : Ball) =         if b.X < Ball.W / 2 then             rightScore <- rightScore + 1             reset b         else if b.X > 800 - Ball.W / 2 then             leftScore <- leftScore + 1             reset b         if b.Y < Ball.H / 2 then             b.Y <- Ball.H / 2             b.BounceY()         else if b.Y > 480 - Ball.H / 2 then             b.Y <- 480 - Ball.H / 2             b.BounceY()     override Game.LoadContent() =         spriteBatch <- new SpriteBatch(this.GraphicsDevice)         background <- contentManager.Load<Texture2D>("xnb/green-field")         left_paddle <- contentManager.Load<Texture2D>("xnb/cow")         ball_texture <- contentManager.Load<Texture2D>("xnb/sheep")         texture <- new Texture2D(this.GraphicsDevice, 1, 1);         texture.SetData([| Color.White |])         reset ball     override Game.Update gameTime =         left.Move Keys.W Keys.S         right.Move Keys.Up Keys.Down         ball.Update()         bounce ball         left.Y <- clampY left.Y         right.Y <- clampY right.Y         if ball.Collide(left) || ball.Collide(right) then             ball.BounceX()     override Game.Draw gameTime =         this.GraphicsDevice.Clear(Color.Beige)         spriteBatch.Begin()         spriteBatch.Draw(background, new Vector2(0.0f, 0.0f), Color.White)         spriteBatch.Draw(left_paddle, left.Bounds, Color.White)         spriteBatch.Draw(left_paddle, right.Bounds, Color.White)         spriteBatch.Draw(ball_texture, ball.Bounds, Color.White)         for i in 1 .. leftScore do             let r = new Rectangle(50 + i * 10, 5, 5, 5)             spriteBatch.Draw(texture, r, Color.Black);         for i in 1 .. rightScore do             let r = new Rectangle(750 - i * 10 - 5, 5, 5, 5)             spriteBatch.Draw(texture, r, Color.Black);         spriteBatch.End()         base.Draw(gameTime) let g = new Game1() try g.Run() finally g.Dispose()

At the end of the post I will link the entire project as well. As you can see it’s very easy to create a game from scratch, thanks to the support of the XNA Framework. The only tangible problem is related to the creation of the sprites file, due to the lack of support for Contents creation in Visual Studio F#.
A possible workaround is to create a dummy C# project, load all your images there and then compile. You will find all the created .xnb files inside the project directory. Finally, you need to copy the generated files into your bin directory. Here is a screenshot:

And there you can download the entire project:

CowPong.zip

Enjoy!