So a short recap -> We began with discussing about a new paradigm of programming – Functional Programming. As a purely functional language haskell seemed to be the best way to learn it. Thus just like any other language we began learning about its interpreter/compiler, how to write simple programs and basic syntax. Then we looked how to use lists and tuples. So far so good!!
Up till now I didn’t touch upon types. A type is a kind of label that every expression has. It tells us in which category of things that expression fits. e.g. ‘Hello’ is a string. Every programming language has its own type system – static/dynamic. Haskell has static type system. Thus before compilation every expression has its type sorted out. This is good as it avoids many errors in advance like dividing a number by string. (Obviously dynamic type system has its own advantages but that is a talk for some other time). Second thing type inference – if we write ‘True’ we don’t have to tell ghc that it is a boolean. So we need not explicitly write types of various expressions.
:t is a ghci option which shows us the type of expression we enter. e.g. “Hello” is [Char] i.e. list of characters.
Prelude> :t "Hello"
"Hello" :: [Char]
Prelude> :t last
last :: [a] -> a
Prelude> :t addthree
addthree :: Int -> Int -> Int -> Int
Hang on, what is this [a] -> a? Remember use of last, it returns last element of a list. So when we ask “interpreter interpreter inside the terminal, what type does last belong?” it cleverly answers that my king(what? I can’t be queen :P) last being a function takes a list of anything, denoted by a, returns something of the type anything. Now anything/a can be numbers, characters or heck even lists. We call a as type variable. Again it means it can be anything. I recommend you try this for many other functions like say ‘and’. ‘and’ being boolean and should take a list of bools(as there may not be only 1 no to and) and returns either true or false i.e. bool. Verify on your own. While the last example is to give you idea what if there are more than one arguments. It simply first writes types of all the arguments and in the last type of return value. (addthree is a hypothetical function which adds 3 nos. there is no such in-built function in haskell).
Yeah so then we have all sorts of types like Interger, Float, Bool, Character, Double just like C or any other language. But haskell has something else as well. It has typeclasses. So what is a typeclass? Well it is something that categorizes/defines a behaviour and its members are ought to follow the same. Now this seems a little confusing. Purists from OOP will argue that this looks something like classes; well apart from similarity in names they are different; like totally! Lets take example as this is a very important concept. So far we haven’t tried ‘:t’ for operators. Let’s try and see what happens :
Prelude> :t (+)
(+) :: Num a => a -> a -> a
Prelude> :t (>)
(>) :: Ord a => a -> a -> Bool
So some funky words came up. ‘Num’ and ‘Ord’, what are they? Well they are predefined typeclasses. ‘+’ is a operator which does numerical operations. ‘>’ is for comparison purposes i.e. Ordering! So ‘Num’ is typeclass which specifies numerical operations and ‘Ord’ specifies ordering. Favoloso! we nailed it. But hey why do we need this boring stuff? It is because we need to write functions. Each and every function must belong to some typeclass. While so far what we wrote were very basic functions so haskell inference was good and we could safely rely upon it. But sometimes we need to define our own typeclass and anyway it better to do things perfectly rather doing them just fine/passable. So what were we missing? So I am defining a function for squaring things
square :: (Num a) => a -> a
square x = x*x
So basically before defining the inner body just define the scope and type using appropriate typeclass. This begins our excursion in functions. Obviously there are lot more cooler things remaining with syntax of functions. And that will be our next agenda. Have fun till then;