Part 1 can be found here
Haskell supports a static type system. That means the type of every object is known at compile time. To check the type of anything in haskell we can use the
Lets try this out in the GHCI
Prelude> :t 'a' 'a' :: Char Prelude> :t "foo" "foo" :: [Char] Prelude> :t (4==5, 'a') (4==5, 'a') :: (Bool, Char)
Not only can Haskell get the data types of variables it can also do the same for functions. Lets take the function
min as an example.
min takes two Ordered entities and returns the minimum one. So for example
min 2 3 2 min 'a' 'b' 'a'
Now what happens when we check the type of
Prelude> :t min min :: Ord a => a->a->a
=> symbol is a class constraint. It means that in the function a represents the
Ord data type.
Ord stands for order, or a set of numerable entites. Now we can see the function takes in two
Ord variables and outputs the same. Note that haskell does not place any major distinction between the parameters and return function. The return type is just the last parameter.
Now lets see what happens with the
map takes a function and a list and maps the elements of the list to their output in the function.
Prelude> :t min map :: (a->b) -> [a] -> [b]
map function takes in the function
(a->b) as a parameter and outputs list of type
Now lets try to create our own functions. We can use two tricks to help get working faster. These are pattern matchinng and guards.
Lets say we
sayHi :: String -> String sayHi "hello" = "What's up?" sayHi "bonjour" = "Come sa?" sayHi x ="Hello"
So what we are doing above is matching the pattern of the input string and returning a string of our own. Lets test it to see the output.
*Main> sayHi "s" "Hello" *Main> sayHi "hello" "What's up?" *Main> sayHi "bonjour" "Come sa?"
Guards take pattern matching a little further by allowing you to check a condition on the input before returning it.
pythogaros :: (RealFloat a) => a -> a -> a-> String pythogaros a b c | a^ 2 + b^2 == c^2 = "Ooh! Got a right angle" | a^ 2 + b^2 > c^2 = "A-cute :-)" | otherwise = "You're pretty obtuse" *Main> pythogaros 3 4 5 "Ooh! Got a right angle" *Main> pythogaros 3 4 6 "You're pretty obtuse" *Main> pythogaros 3 4 6
Now lets say instead of just pattern matching we want to do stuff to the input before giving it to the rest of the function.
In this function we constrain the type of
a to be a
RealFloat and a
RealFloat is so we can do floating point math and
Show is for displaying it as a string.
let command lets us set the area and proceed to use that in the rest of the function
rect :: (RealFloat a,Show a) => a -> a -> String rect l b = let area = l * b in "Area is "++ area *Main> rect 3 4 "Area is 12.0" *Main> rect 3.555 4.592 "Area is 16.324559999999998"
More higher order stuff to come in Part 3 (if I ever get around to writing it)