Sunday 1 May 2016

Haskell: Eq type class


Eq class defines operators ==, /= for equality tests. Your custom types must derive the class Eq, to use ==, /= operators.

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
 
Observe above custom type Employee, it is not deriving Eq class, so you can 't perform equality tests on it.
*CustomTypes> :load CustomTypes.hs
[1 of 1] Compiling CustomTypes      ( CustomTypes.hs, interpreted )
Ok, modules loaded: CustomTypes.
*CustomTypes> 
*CustomTypes> let engineer1 = Engineer "Hare" "Ram" 1
*CustomTypes> let engineer2 = Engineer "Ram" "Krishna" 2
*CustomTypes> 
*CustomTypes> engineer1 == engineer2

<interactive>:21:11:
    No instance for (Eq Employee) arising from a use of ==
    In the expression: engineer1 == engineer2
    In an equation for it: it = engineer1 == engineer2
*CustomTypes> 


To perform equality tests on the type Employee, you must derive (deriving Eq) the type class Eq.

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 (Eq)


Now you can use ==, /= operators on custom type.
*CustomTypes> :load CustomTypes.hs
[1 of 1] Compiling CustomTypes      ( CustomTypes.hs, interpreted )
Ok, modules loaded: CustomTypes.
*CustomTypes> 
*CustomTypes> let engineer1 = Engineer "Hare" "Ram" 1
*CustomTypes> let engineer2 = Engineer "Ram" "Krishna" 2
*CustomTypes> let engineer3 = Engineer "Hare" "Ram" 1
*CustomTypes> let engineer4 = Engineer "Hare" "Ram" 3
*CustomTypes> 
*CustomTypes> engineer1 == engineer2
False
*CustomTypes> engineer1 == engineer3
True
*CustomTypes> engineer1 == engineer4
False
*CustomTypes> engineer1 /= engineer2
True
*CustomTypes> engineer1 /= engineer2
True
*CustomTypes> engineer1 /= engineer3
False
*CustomTypes> engineer1 /= engineer4
True
*CustomTypes> 


When you use the statement ‘deriving (Eq)’, Haskell provides default implementation for you, You can override this behaviour by using instance statement.

For example, as per my requirement two employees are equal if their ids are equal, else not. I updated my CustomTypes.hs file to meet new requirement 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


    {- Overriding == functionality -}
    instance Eq Employee where
        (==) (Engineer fName1 lName1 id1) (Engineer fName2 lName2 id2) = (id1 == id2) 
        (==) (Manager fName1 lName1 id1 noOfReportees1) (Manager fName2 lName2 id2 noOfReportees2) = (id1 == id2) 
        (==) (Director fName1 lName1 id1 noOfReportees1) (Director fName2 lName2 id2 noOfReportees2) = (id1 == id2)

*CustomTypes> :load CustomTypes.hs
[1 of 1] Compiling CustomTypes      ( CustomTypes.hs, interpreted )
Ok, modules loaded: CustomTypes.
*CustomTypes> 
*CustomTypes> let engineer1 = Engineer "Hare" "Ram" 1
*CustomTypes> let engineer2 = Engineer "Rama" "Krishna" 1
*CustomTypes> let engineer3 = Engineer "Hare" "Ram" 3
*CustomTypes> 
*CustomTypes> engineer1 == engineer2
True
*CustomTypes> engineer1 == engineer3
False
*CustomTypes> 


You may get doubt, I implemented only (==) function, is it work for (/=) function ? Yes absolutely, it works for (/=) function also.
*CustomTypes> engineer1 /= engineer2
False
*CustomTypes> engineer1 /= engineer3
True


How above code is working for (/=), even though I am not implemented it?
Type class Eq declared two functions ==, /=. It provides default implementation for /=, == functions. If we didn’t explicitly define /=, compiler automatically uses the default implementation given in the type class Eq.


 
Previous                                                 Next                                                 Home

No comments:

Post a Comment