# Learn You a Haskell for Great Good!

## Believe the type

- Haskell has a static type system
- type of every expression is known at compile time, leads to safer code
- check type for both variable and functions
- :t

- x has type of t
- x :: t

- element in a list must have the same type
- e.g. “HELLO!” :: [Char]

- element in a tuple can have different type
- e.g. (True, ‘a’) :: (Bool, Char) or (‘a’, ‘b’, ‘c’) :: (Char, Char, Char)

- function declaration
- e.g. removeNonUppercase :: [Char] -> [Char]
- mapping string to string

- String is equivalent to [Char]
- function declaration with multiple parameters
- e.g. addThree :: Int -> Int -> Int -> Int
- mapping the first three Int as parameters and the last item as return type

- Some common types and all types start with a Capital letter
- Int stands for Integer but bounded with minimum and maximum values
- Integer stands for Integer also but without bound.
- Float is single precision real floating point number.
- Double is double precision real floating point number.
- Bool is a boolean type (True or False).
- Char is a character.

## Type variables

- type variable is use to represent any type and are usually given names like a, b, c, …
- e.g. :t head will result head :: [a] -> a
- this mean head operate on a list of type a and return an element of type a.
- e.g. :t fst will result fst :: (a, b) -> a
- this mean fst operate on a tuple pair of type a, b and return an element of type a (the first element of the tuple)

## Typeclasses 101

- typeclasses is a sort of interface that defines some behavior.
- e.g. :t (==) will gives (==) :: (Eq a) => a -> a -> Bool
- Note: == is a function and comprise of only special characters, so it is consider to be infix function by default, use parentheses to call it as a prefix function (e.g. infix a==b vs prefix (==) a b).
- equality function takes any two parameters that are of same type and return a Bool.

- class constraint, =>
- Some basic typeclasses
- Eq typeclass provides an interface for testing for equality
- e.g. == or /=

- Ord takes two values of same type and returns an ordering.
- e.g. parameter >, <, >= and <=
- To be a member of Ord, a type must first have membership in Eq.

- Ordering is a type that can be GT, LT or EQ.
- Show can be presented as strings. All types covered so far except function are a part of Show. show function deals with the Show typeclass.
- e.g. show 3 gives “3”

- Read is sort of the opposite of typeclass of Show.
- e.g. read “6” – 1 gives 5
- However, read “6” alone will give an error because GHCi cannot infer what type it suppose to be.
- Using explicit type annotations to solve the issue
- e.g. read “6” :: Float gives 6.0

- Enum members are sequentially ordered types.
- e.g. [LT .. GT] gives [LT,EQ,GT]
- e.g. succ ‘B’ gives ‘C’

- Bounded members has upper and lower bound
- e.g. minBound :: Int gives the lower bound of integer (depend on architectural)
- e.g. maxBound :: Bool gives True
- All tuple are also part of Bounded if Bounded components are in it.

- Num is a numeric typeclass. It includes all numbers.
- e.g. :t 20 gives 20 :: (Num t) => t
- To join Num, a type must already be friends with Show and Eq

- Integral is also numeric typeclass that include only whole numbers
- Floating includes only floating point numbers.
- fromIntegral x
- signature of fromIntegral has multiple constraint (Num b, Integral a) => a -> bturn Integral type to more general number
- e.g. length function return Int type instead of Num type

- Eq typeclass provides an interface for testing for equality

Advertisements
(function(g,$){if("undefined"!=typeof g.__ATA){
g.__ATA.initAd({collapseEmpty:'after', sectionId:26942, width:300, height:250});
g.__ATA.initAd({collapseEmpty:'after', sectionId:114160, width:300, height:250});
}})(window,jQuery);
var o = document.getElementById('crt-345474934');
if ("undefined"!=typeof Criteo) {
var p = o.parentNode;
p.style.setProperty('display', 'inline-block', 'important');
o.style.setProperty('display', 'block', 'important');
Criteo.DisplayAcceptableAdIfAdblocked({zoneid:388248,containerid:"crt-345474934",collapseContainerIfNotAdblocked:true,"callifnotadblocked": function () {var o = document.getElementById('crt-345474934'); o.style.setProperty('display','none','important');o.style.setProperty('visbility','hidden','important'); } });
} else {
o.style.setProperty('display', 'none', 'important');
o.style.setProperty('visibility', 'hidden', 'important');
}
var o = document.getElementById('crt-750971480');
if ("undefined"!=typeof Criteo) {
var p = o.parentNode;
p.style.setProperty('display', 'inline-block', 'important');
o.style.setProperty('display', 'block', 'important');
Criteo.DisplayAcceptableAdIfAdblocked({zoneid:837497,containerid:"crt-750971480",collapseContainerIfNotAdblocked:true,"callifnotadblocked": function () {var o = document.getElementById('crt-750971480'); o.style.setProperty('display','none','important');o.style.setProperty('visbility','hidden','important'); } });
} else {
o.style.setProperty('display', 'none', 'important');
o.style.setProperty('visibility', 'hidden', 'important');
}