Home

TODO is the smallest airport in the world, it can only hold 3 planes at any time.

You are the air traffic controller there, and your job is to plan the landings and taking off of all the planes so that no accidents happen.

This job is not too difficult, you just have to look at the landing and taking-off sequence, and determine if the airport can accomodate the sequence.

Let’s model that.

type Planes = Int
type Airport = Planes

Planes can land, or take off:

land :: Planes -> Airport -> Airport
land incoming grounded = grounded + incoming

takeoff :: Planes -> Airport -> Airport
takeoff flying grounded = grounded - flying

We can try landing and taking off:

> takeoff 1 (land 2 0)
1
> takeoff 2 (land 3 (takeoff 1 (land 2 0)))
0
> `land` 2 `takeoff` 1 `land` 3 `takeoff` 2
2

The second example seems to be okay, but actually we had let 4 planes in the airport at once. Let’s fix that using Maybe.

When we have too many planes, we return a Nothing, meaning that this particular sequence can not be accomodated safely by the airport.

land :: Planes -> Airport -> Maybe Airport
land incoming grounded
  | grounded + incoming > 3 = Nothing
  | otherwise               = Just (grounded + incoming)

takeoff :: Planes -> Airport -> Maybe Airport
takeoff flying grounded
  | grounded - flying < 0 = Nothing
  | otherwise             = Just (grounded - flying)

Let’s try this:

> land 3 0
Just 3
> land 4 0
Nothing
> takeoff 2 0
Nothing
> takeoff 1 2
Just 1

Now we have a problem because we can no longer chain our land and takeoff methods together easily. They both return a Maybe Airport, but they take in Airport. We can try to write a function to take care of this.

chain :: Maybe Airport -> (Airport -> Maybe Airport) -> Maybe Airport
chain Nothing _ = Nothing
chain (Just grounded) action = action grounded

And we can now write things smoothly

> Just 1 `chain` takeoff 1 `chain` land 2 `chain` takeoff 2
Just 0

And if we just change the name of chain to >>=

> Just 1 >>= takeoff 2
Nothing
> Just 2 >>= takeoff 1
Just 1

There we have it, the bind operator in Monads!