Learning Haskell through Maybe – Functors

Types

You have a Type, Integer. Integer is an integer, representing intergers, just like real life.

Other types are Char, which are characters such as 'a', 'b' etc. The one we will look at in detail is Maybe.

Type variable, constructors

A data of type Maybe can only be made if a type variable is specified. This means that you can make a Maybe Integer, Maybe Char, but a Maybe isn’t a complete type.

The way to make a data of type Maybe is to use a type constructor. Maybe has two type constructors, Just and Nothing. Just is like Maybe, it can only be made if a type variable is specified. Nothing can be made simply on its own, it is a complete type.

Let’s try making Maybes in GHCI:

> let best_friends = Just 1
> best_friends
Just 1

You have just used the type constructor Just, passed in the Int 1, to make a type of Maybe Int. To verify the type of best_friends:

> :t best_friends
best_friends :: Maybe Integer

:: can be read as is of type. How about make a Maybe using Nothing?

> let girlfriend = Nothing
> girlfriend
Nothing

Functor

Suppose you have twice as many best friends as I do, how can I find out how many best friends you have?

> let your_best_friends = 1 * 2 --hard coded value for the number best friends I have
> your_best_friends
2
> let your_best_friends = best_friends * 2 --fails terribly

You get a crazy error message. It means that you cannot multiply 2 with best_friends, because best_friends is not a type that can be multiplied with 2. Clearly there is something going on here, because best_friends can contain an Integer, and we can definitely multiply Integers, what we can do is to define a function that helps us do so.

> :{
| let calc_friends :: Maybe Integer -> Maybe Integer
|       calc_friends Nothing = Nothing
|           calc_friends (Just x) = Just (x * 2)
> :}
> let your_best_friends = calc_friends best_friends
> your_best_friends
Just 2

What we did was to define a function that can calculate the number of best friends you have, given the number of best friends I have. By applying this function to best_friends, you get the number of best friends you have, wrapped in a Just. What if I told you that you had twice as many girlfriends as I do?

> let your_girlfriends = calc_friends girlfriend
> your_girlfriends
Nothing

Hahaha.

Perhaps you grow more popular, and you actually had 3 times more friends than I do. Since we hard coded the value 2, we have to make another function with the value 3, or we can actually generalize the function as such.

> :{
| let calc_friends :: (Integer -> Integer) -> Maybe Integer -> Maybe Integer
|     calc_friends _ Nothing = Nothing
|     calc_friends f (Just x) = Just (f x)
> :}
> let your_best_friends = calc_friends (* 3) best_friends
> your_best_friends
Just 3
> let your_girlfriends = calc_friends (* 2) girlfriend
> your_girlfriends
Nothing

We define calc_friends as a function that takes in another function, f, and this function f takes in an Integer and returns another Integer. An example of this function would be (* 3). calc_friends also takes in a Maybe Integer, which it will apply the function f to, and returning a resut of type Maybe Integer

What if instead of number of best friends, an Integer, we wanted to compare height, a Double, and you are 1 metre taller than me, this looks pretty similar to calc_friends, so let’s reuse that:

> let height = Just 1.7
> let calc_height = calc_friends (+ 1)
> calc_height height

Throws you an error about incompatible types. This is becase we defined calc_height in terms of calc_friends, which only worked with Maybe Integer, but our height was a Maybe Double. So let’s generalize our function using type variables, just like how Maybe is defined.

> :{
| let calc_stuff :: (a -> a) -> Maybe a -> Maybe a
|     calc_stuff _ Nothing = Nothing
|     calc_stuff f (Just x) = Just (f x)
> :}
> calc_stuff (* 3) best_friends
Just 9
> calc_stuff (+ 1) height
Just 2.7
> calc_stuff (* 2) girlfriend
Nothing

The last bit to understanding Functor is a method called fmap, all types that are instances of the typeclass Functor have to implement a method called fmap, which has the signature:

fmap             :: (a -> b) -> f a -> f b 
calc_stuff :: (a -> a) -> Maybe a -> Maybe a

I’m putting them one above the other to let you see how similar they are. fmap is just calc_stuff generalized
– generalizing the function that calc_stuff takes in and
– generaizing the type Maybe to other types that take in a single type variable

And the f we see in the fmap is the Functor, a typeclass of which Maybe is an instance of.

Advertisements
Aside

ASUS UX302LG Quick Review

I’m typing this on my one-week-old ultra-book, a ASUS UX302LG. I recall one morning in December, I was researching on which laptop to buy at SITEX 2014, when I coincidentally saw a video preview of UX302. I remember being in shock at how gorgeous it looked – Gorilla Glass cover, brushed metal finish all over the laptop, 1920 x 1080 HD Touchscreen, and what insane specs it came in – i7 Haswell, 4GB RAM, NVIDIA GeForce 730m. I made the decision to pre-order the UX302 at SITEX, even before I laid my hands on one of them, I knew I wanted it. And frankly, I regret nothing.

I figured that many people would be considering the UX302, because it is a serious contender, and since there aren’t many reviews already out there, I shall do a quick review of this amazing device.

The Package

Image

I haven’t had many laptops before, but ASUS really did a great job for the UX302. The container is a sleek, black, smooth box, it looked so pristine I almost didn’t dare to touch it. When I touched it my sweat marks would stay on the box for a slight moment, then evaporates before my very eyes. Awesome. Some say that they are copying Apple with the box, but I say do whatever looks great. This box really fits the design language of the UX302, sleek, high-end, modern, beautiful.

The Laptop

And when you open the box up you get this:

Image

Once again, very sleek and neat. I could instantly see where my money went, into this piece of beautiful, shiny metal. Precious. In the small compartment on the right sits all the various components

The Rest

IMG_20140101_153729

Neatly lined up, from top to bottom, left to right: laptop, laptop sleeve, user manual, quick start guide, warranty (I think), cable tie, charger head, charger adapter, USB-Ethernet adapter, Display Port-VGA adapter, accessories pouch. Not shown: cleaning cloth (the size of the keyboard)

Special note about the laptop sleeve: I was pleasantly surprised that it came with the laptop. Before I collected the laptop, I was already thinking of getting a nice sleeve, but now that ASUS as kindly given me a black leather sleeve, I guess there’s nothing for me to worry!

How It Has Been

One week of use and the experience is just amazing. Everything looks great on the HD screen, movies, videos, YouTube. The speakers are awesome (Bang & Olufsen Technology) – I’m not an audio person so I can’t say much beyond the speakers being loud and clear. Dota 2 runs smooth as butter, although I can’t seem to set it to 1920×1080 resolution, no complains tho, it still looks sick. Windows 8 is better that I imagined, in some ways. Start up times are sick: press the power button, turn to go toilet, reach the door, turn back because it is already booted. Battery life is heavenly, especially considering my previous laptop 1.5 hrs. I haven’t exactly measured, but I feel safe bringing it out to school without packing the charger, although the charger doesn’t add much weight. Touch pad is smooth and responsive, though I think it still doesn’t match the Macbook’s. The norms are there though, double finger scrolling, three finger down minimize, edge swiping. Oh and adjustable keyboard backlighting!

It isn’t without its flaws though. The spacebar is betting a bit squeaky, but only the left edge, but that is where I usually type – and maybe I should change this habit. Linux compatibility totally blows though. I wanted to install Ubuntu or Linux Mint alongside Windows 8 for double booting, but always got a blank screen after selecting “Install Now” at the menu. The screen isn’t on 0 brightness, I’ve tried – fn+f7 turns the display off and there’s an obvious difference. Tried editing the boot parameters: nomodeset, didn’t help. I sort of gave up at that: if there is a need for Linux I will just virtualize, until I discover some other method. Sometimes after it wakes from sleep, the Windows UI becomes too small. I think usually they scale up the icons and font size so that it’s readable on the display, but when it sleeps and wakes it fails to do so.

Final Words

If you are looking for a Windows ultra book right now, the UX302 is the one to get. I have read, and sometime tried, other ultra books, but the UX302 is pretty much unmatched in terms of specifications, design, quality, build and price. I got mine for $1798 because it was $200 off at the fair, which means if you purchase it right now it would be just under $2000. It’s not cheap, but you get what you pay, and UX302 really delivers.

Summer 2013

There isn’t exactly a summer over here, but it’s just simpler to call it that. So, the long awaited summer holidays are already here, and it can only go two ways:

  1. Do nonsense
  2. Do useful stuff

Now, number 2 is obviously the the preferred option, but it is kind of vague. So I made a plan, now I’m a man with a plan:

Badly drawn mind map

Badly drawn mind map

I classified the useful stuff that I can do into two broad categories: Self and Others.

Self is well, about myself. My mind, heart, body. Others has to do with, surprise, other people! And those people are my family and friends. The idea behind this plan is self-improvement, without disregarding the relationships I have with people and also my social life. Notice that there is a bit of an overlap between Heart (which has to do with Self), and Others. Which I feel is natural. This actually brings to mind a Chinese proverb along the lines of

“Train yourself, grow a family, rule the country, make world peace”*

You need to start working on yourself, before you can move on to bigger things.

I identified numerous activities I can do to achieve my goals, but since I have only ~90 days, I narrowed it down to these five:

  • Orbital (Mind: consolidating knowledge)
  • Design (Mind: acquiring new knowledge, exploration)
  • Basketball (Body: health and fitness)
  • Family dinners (Heart: kinship)
  • Orientation camps (Heart: friendship, social life)

For ease of remembering, I formulated the acronym DOFOB. It is meant to be pronounced like DAFUQ, but just with DOFOB. Anyway, 5 goals, 90 days; I think I can manage.

* That’s an absolutely horrible translation, but I hope you get the idea. Start from yourself, then slowly effect change in the bigger picture.

Some quick guidelines to Clean Code

I recently read Clean Code by Robert C. Martin, and here is a very summarized compilation of tips/principles that I understoo or found useful.

Naming

Names should convey correct meaning. (descriptive and correct)
Names should be pronounceable.
Names should be searchable.

Functions

Functions should be small, < 10 lines.
Functions should do one thing and do it well.
A function that takes 2 parameter is good. A function that takes 1 is better. A function that takes 0 is best.
Avoid flag arguments (i.e. Boolean values), it shows that a function does >1 thing.
Functions should not have side effects (i.e. do things other than stated in its name).

Comments

Avoid comments if possible, your code should be explanatory.
Good comments: explaining intent, clarification of obscure parts, amplification of seemingly unimportant parts, TODO, warnings.
Bad comments: redundant, misleading, journal.

Formatting

Small files are easier to understand than big files.
Newspaper metaphor: Headline -> Quick summary/Gist -> Details.
Use blank lines to separate different concepts.
Code that is related should be close together e.g. variable declarations in a loop.
Use white space between words to emphasize relation.
There are no laws for indentation, just set rules within the team and stick to them.

Objects and Data Structures

Objects hide data behind abstractions and expose functions that operate on the data.
Data Structures are containers for data and have no meaningful functions.
Avoid train wrecks (i.e. someThing().anotherThing().lastThing().orIsIt()).

Errors

Use exceptions instead of return codes, this enables separation of error checking and function logic.
Write try-catch statements first (in line with TDD).
Write Unit Tests.
Three laws of TDD:
1 – You may not write production code until you have written a failin test.
2 – You may not write more of a unit test than is sufficient to fail, and not compiling is failing.
3 – You may not write more production code than is sufficient to pass the currently failing test.
Tests, like your production code, should be clean.
Single concept per test.

Classes

Classes should be small, just like functions.
Single Responsibility Principle (SRP), a class or module should have one, and only one, reason to change.
Classes should be open for change.

Good Designs (Rules by Kent Beck)

1 – Runs all the test
2 – Contains no duplication
3 – Expresses the intent of the programmer
4 – Minimizes the number of classs and methods

Successive Refinement

Quickview for YouTube

-UPDATE- My first user review on Chrome Web Store 😀

5-stars yay!

5-stars yay!

I released Quickview for Youtube on the Chrome Web Store last right, it was a really exciting 30 mins.

Beads of sweat trickling down my faces as I waited in anticipation for the zip file complete uploading, cursor hovering above the “Pubish now” button, as if I need to click it before it disappears suddenly. “Completed.” Within a split second I pressed my mouse left button as hard as I could and then it was live, on the Chrome Web Store. I would get millions of users and everyone would love what I did. But first let me see if it works. Bam. Reality strikes hard. I uploaded a wrong version. “Take it down, take it down” I told myself as I maneuvered what seemed like a labyrinth of links to finally reach the console where I could remove it. No way I was going to ship something that broken. Within minutes, things have turned out well.

Perhaps things weren’t that dramatic but it really was a unnerving experience publishing my first Chrome extension. But that night I did so, friends told me they are using it, liked it, and shared it with their friends. So I’m very happy they found it useful.

From a technical perspective, this extension is definitely not difficult. I had to learn bits about DOM, constantly refer to the jQuery API, check out Web Platform and the MDN; and I’m really glad there are so many great resources for anyone interested. I recently read a book called Clean Code by Robert C. Martin, and I wanted to apply some principles I learned, such as proper meaningful naming, and simple do one thing functions. It is not as DRY as I like it to be, so there’s lots of room for improvement.  While building Quickview, I had moments where I needed to decide which was the better way to do things. Here I learned something about trade-offs, such as clever-looking code v.s. maintainability.

I have a long way to go, but Quickview is definitely a small step, and hopefully in the right direction.

PS. Quickview is open-source.

10 Rules for a Productive Programmer

I just read The Productive Programmer by Neal Ford, and this is my takeaway:

10 Rules for a Productive Programmer.

Rule 1: Never do things your computer can do faster than you

This applies to finding files, launching applications.

Rule 2: Those who forget history are condemned to repeat.

Command history (Ctrl+R in bash), clipboard (in your editors), web history, macros.

Rule 3: Turn off needless notifications

Email/ does not need to be checked every 5 minutes.

Rule 4: Computers are for automation, use them.

If you notice yourself repeating some steps, automate!

Rule 5: Test

Testing makes you less fearful of changing things. It ensures that things always work. And it allows you to benchmark

Rule 6: YAGNI

(There’s no explanation here ‘cos YAGNI!)

Rule 7: Occam’s Razor

When given multiple explanations for something, the simplest is the most likely.

Rule 8: Law of Demeter

For any object or method, the only methods that should be invoked are:
– The methods of the object itself,
– parameters of the method
– any objects created within the method.

Rule 9: Question authority

The idea here is not revolting, but rather seeking explanations, for current processes and practices.

Rule 10: Use the perfect tool

The perfect tool is the one you know best, so find one that satisfy your requirements, use it, learn it inside out and master it.

Space Apps Challenge 2013

I participated in the NASA-backed Space Apps Challenge (Singapore) last week, here some some reflections.

The first thing about this challenge (and practically any other hackathon) is that there is very little time. Some events discourage planning before coming down, but Space Apps specifically asked the participants to decide their project early and do some preliminary reading. Which I didn’t. ‘Cos I was busy with school and stuff. Also, I went down as an individual. So the lack of prior communication meant that we spent a good hour talking about how we are going to do things. Nonetheless, I enjoyed meeting new people, making friends, it was a fun experience. Also, despite having decided on a challenge to work on prior to the event, I was unable to form a team due to a lack of interest in the topic I chose. On hindsight, I think that I would have been able to convince people if I had some some prior research or produced a mock-up. This would show my commitment.

The challenge was not a overnight hackathon. Staying over was not mentioned, and I conveniently went home. I felt that this had some negative impacts on the final product: less time to hack, inertia the next day, context switching… In short, hackathons should really be all-nighters, that’s what makes them fun, and challenging, and unhealthy. Buy hey, it’s only once in a while right? 😉

I loved the challenges that were suggested. They were very interesting and open ended, hence we could do whatever we want. Throughout the challenge, my team had to do quite a bit of research, and I think in the end, we got more out of the challenge than what we gave to it. Shameful in a way, but brilliant.

My team won the Big Vision award, for our implementation of a website that talks about NASA’s impact on the economy, as well as effect on humanity. Our website also has a little “crowdfunding” side to it, where we allow the public to indicate interest in NASA projects, so that NASA has leverage to request for more funds.

Overall, I had a great experience: two eye-opening talks during the event, many new friends, more knowledge about NASA. I’m looking forward to next year’s Space Apps Challenge, and next time I will be more prepared.