By using type classes we can define a
generic interface that contain common operations applicable to number of types.
Let me explain with an example.
For example, I want to develop an
application for company XYZ. There are
three types of employees (Engineer, Manager, Director). My custom types are look
like below.
CustomTypes.hs
module CustomTypes where type FirstName = String type LastName = String type EmpId = Integer type NoOfReportees = Integer {- Define an employee type -} data Employee = Engineer FirstName LastName EmpId | Manager FirstName LastName EmpId NoOfReportees | Director FirstName LastName EmpId NoOfReportees
I just want to
display employee information to the console. Following methods do the task.
showEngineer (Engineer firstName lastName empId) = (firstName ++ " : " ++ lastName ++ " : " ++ (show empId)) showManager (Manager firstName lastName empId noOfReportees) = (firstName ++ " : " ++ lastName ++ " : " ++ (show empId) ++ " : " ++ (show noOfReportees)) showDirector (Director firstName lastName empId noOfReportees) = (firstName ++ " : " ++ lastName ++ " : " ++ (show empId) ++ " : " ++ (show noOfReportees))
After adding above methods my
CustomTypes.hs file looks like below.
CustomTypes.hs
module CustomTypes where type FirstName = String type LastName = String type EmpId = Integer type NoOfReportees = Integer {- Define an employee type -} data Employee = Engineer FirstName LastName EmpId | Manager FirstName LastName EmpId NoOfReportees | Director FirstName LastName EmpId NoOfReportees showEngineer (Engineer firstName lastName empId) = (firstName ++ " : " ++ lastName ++ " : " ++ (show empId)) showManager (Manager firstName lastName empId noOfReportees) = (firstName ++ " : " ++ lastName ++ " : " ++ (show empId) ++ " : " ++ (show noOfReportees)) showDirector (Director firstName lastName empId noOfReportees) = (firstName ++ " : " ++ lastName ++ " : " ++ (show empId) ++ " : " ++ (show noOfReportees))
Prelude> :load CustomTypes.hs [1 of 1] Compiling CustomTypes ( CustomTypes.hs, interpreted ) Ok, modules loaded: CustomTypes. *CustomTypes> *CustomTypes> let engineer1 = Engineer "Hari Krishna" "Gurram" 1 *CustomTypes> let manager1 = Manager "Anand" "Bandaru" 2 24 *CustomTypes> let director1 = Director "Sailaja" "PTR" 1234 58 *CustomTypes> *CustomTypes> showEngineer engineer1 "Hari Krishna : Gurram : 1" *CustomTypes> *CustomTypes> showManager manager1 "Anand : Bandaru : 2 : 24" *CustomTypes> *CustomTypes> showDirector director1 "Sailaja : PTR : 1234 : 58" *CustomTypes>
Lets go back to the code, Don't you
think the functions showEngineer, showManager, showDirector are doing same
task, I mean just displaying the values associated with their fields like
FirstName, LastName, EmpId etc., What if there is a way, I can put this common
functionality into some place, and my custom types can able to use this common
functionality without duplicating the code. There type classes come into
picture.
For Example, Haskell provide a built-in
type class Show, which has function show in it.
show :: (Show a) => a -> String
show function takes an argument a, which
is instance of class Show and convert a to String.
We can use the functionality provided by
Show class by deriving (deriving (Show)) it in our custom types like below.
Update CustomTypes.hs like below.
CustomTypes.hs
module CustomTypes where type FirstName = String type LastName = String type EmpId = Integer type NoOfReportees = Integer {- Define an employee type -} data Employee = Engineer FirstName LastName EmpId | Manager FirstName LastName EmpId NoOfReportees | Director FirstName LastName EmpId NoOfReportees deriving (Show)
Prelude> :load CustomTypes.hs [1 of 1] Compiling CustomTypes ( CustomTypes.hs, interpreted ) Ok, modules loaded: CustomTypes. *CustomTypes> *CustomTypes> let engineer1 = Engineer "Hari Krishna" "Gurram" 1 *CustomTypes> let manager1 = Manager "Anand" "Bandaru" 2 24 *CustomTypes> let director1 = Director "Sailaja" "PTR" 1234 58 *CustomTypes> *CustomTypes> show engineer1 "Engineer \"Hari Krishna\" \"Gurram\" 1" *CustomTypes> *CustomTypes> show manager1 "Manager \"Anand\" \"Bandaru\" 2 24" *CustomTypes> *CustomTypes> show director1 "Director \"Sailaja\" \"PTR\" 1234 58"
You can get rid of escape sequences from
output, by using putStrLn function.
Prelude> :load CustomTypes.hs [1 of 1] Compiling CustomTypes ( CustomTypes.hs, interpreted ) Ok, modules loaded: CustomTypes. *CustomTypes> *CustomTypes> let engineer1 = Engineer "Hari Krishna" "Gurram" 1 *CustomTypes> let manager1 = Manager "Anand" "Bandaru" 2 24 *CustomTypes> let director1 = Director "Sailaja" "PTR" 1234 58 *CustomTypes> *CustomTypes> show engineer1 "Engineer \"Hari Krishna\" \"Gurram\" 1" *CustomTypes> *CustomTypes> show manager1 "Manager \"Anand\" \"Bandaru\" 2 24" *CustomTypes> *CustomTypes> show director1 "Director \"Sailaja\" \"PTR\" 1234 58"
What
are Type classes?
Type classes define number of functions
and any types that are deriving these type classes can use these functions (or)
can override this default behavior.
Is
this type classes are same like classes in Java?
Absolutely not. They have more in common
with interfaces, in that they specify a series of methods or values by their
type signature, to be implemented by an instance declaration.
No comments:
Post a Comment